Вызывание шаблонной функции без <>; вывод типа

Если у меня есть шаблон функции с typename T, где компилятор может установить тип отдельно, я не должен писать тип явно, когда я вызываю функцию как:

template < typename T > 
T min( T v1, T v2 ) {
   return ( v1 < v2 ) ? v1: v2;
}
int i1 = 1, i2 = 2; int i3 = min( i1, i2 ); //no explicit <type> 

Но если у меня есть шаблон функции с двумя различными именами типов как:

template < typename TOut, typename TIn >
TOut round( TIn v ) {
   return (TOut)( v + 0.5 );
}
double d = 1.54;
int i = round<int>(d); //explicit <int>

Действительно ли это верно, что я всегда должен указывать по крайней мере 1 имя типа? Я предполагаю, что причина состоит в том, потому что C++ не может отличить функции между различными типами возврата.

Но если я использую пустую функцию и передачу ссылка, снова я не должен явно указывать имя типа возврата:

template < typename TOut, typename TIn > 
void round( TOut & vret, TIn vin ) {
   vret = (TOut)(vin + 0.5);
}
   double d = 1.54;
   int i; round(i, d); //no explicit <int>

Если заключение состоит в том, чтобы избежать функций с возвратом, и больше предпочитает void функции, которые возвращаются через ссылку при записи шаблонов? Или есть ли возможность постараться не явно писать тип возврата? Что-то как "вывод типа" для шаблонов. Действительно ли "вывод типа" возможен в C++ 0x?

11
задан Jamal 17 November 2015 в 03:27
поделиться

3 ответа

Разрешение перегрузки выполняется только на основе аргументов функции; возвращаемое значение вообще не используется. Если возвращаемый тип не может быть определен на основе аргументов, вам придется указать его явно.

Я бы не стал «возвращать» значение через ссылочный параметр; что делает неясным код вызова. Например, я бы предпочел следующее:

double x = round<double>(y);

этому:

double x;
round(x, y);

, потому что в последнем случае легко спутать ввод и вывод, и совсем не ясно, что x модифицируется.

В частном случае раунда вам, вероятно, в любом случае понадобится только один или два типа для TOut , так что вы можете просто не указывать этот аргумент шаблона:

template<typename TIn>
int roundToInt(TIn v) {
    return (int)(v + 0.5);
}

Я нахожу roundToInt (x) немного понятнее, чем round (x) , потому что ясно, для чего используется тип int .

16
ответ дан 3 December 2019 в 05:33
поделиться

Позвольте мне добавить к тому, что сказали другие, сказав, что вы должны предпочесть кастинг C++, а не кастинг в стиле C.

vret = (TOut)(vin + 0.5);

против

vret = static_cast<TOut>(vin + 0.5);

статического приведения всегда будет неудачным, если вы попытаетесь преобразовать несвязанные типы. Это может помочь при отладке.

2
ответ дан 3 December 2019 в 05:33
поделиться

вывод состоит в том, чтобы избегать функций с возвратом и больше предпочитать пустые функции, которые возвращаются через ссылку при написании шаблонов

Нет, почему? Что вы получаете? Только ввод вывода (так что меньше кода для написания). Но вы теряете гораздо более логичный синтаксис присвоения значения (и, следовательно, больше кода для написания). Так что одно выиграл, другое проиграл. Я не вижу пользы в целом.

Возможно, даже help придется явно указать тип шаблона: рассмотрим случай lexical_cast. Если не указать тип возвращаемого шаблона, это сведет с толку.

3
ответ дан 3 December 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: