2010-05-27 5 views
1

Я создал простую функцию с двумя аргументами шаблона diffrernt t1, t2 и возвращаемым типом t3. Пока не ошибка компиляции. Но когда Itry вызывать функцию из main, я сталкиваюсь с ошибкой C2783. Мне нужно было знать, если следующий код законно нормально? Если нет, то как это исправлено? , пожалуйста, помогите!Странная ошибка шаблона: ошибка C2783: не удалось вывести аргумент шаблона

template <typename t1, typename t2, typename t3> 
t3 adder1 (t1 a , t2 b) 
    { 
     return int(a + b); 
    }; 


int main() 
{ 
     int sum = adder1(1,6.0); // error C2783 could not deduce template argument for t3 
     return 0; 
} 

ответ

10

Там нет никакого способа для компилятора вывести t3 из аргументов функции. Вы должны передать этот аргумент явно. Изменение порядка параметров, чтобы сделать это возможным

template <typename t3, typename t1, typename t2> 
t3 adder1 (t1 a , t2 b) 
    { 
     return t3(a + b); // use t3 instead of fixed "int" here! 
    }; 

Тогда вы можете вызвать его с adder1<int>(1, 6.0). Это сложнее, если вы хотите вывести t3 в фактический результат добавления. C++ 0x (следующий C++ версии в Кодовое) позволит сделать это, говоря, что тип возвращаемого значения равен типу добавления следующим образом

template <typename t1, typename t2> 
auto adder1 (t1 a , t2 b) -> decltype(a+b) 
    { 
     return a + b; 
    }; 

Тогда вы могли бы бросить Явно в точке использования

int sum = (int) adder1(1,6.0); // cast from double to int 

Имитировать это в текущей версии C++, будет непросто. Вы можете использовать мой promote template для этого. Если вы чувствуете, что это довольно смущает вопрос для вас, и что вы в порядке, явно предоставляя тип возврата, я думаю, что лучше остановиться, явно предоставляя его. Как Herb Sutter says «Напишите, что вы знаете, и знать, что вы пишете»

Nontheless вы можете сделать выше, как это с этим шаблоном

template <typename t1, typename t2> 
typename promote<t1, t2>::type adder1 (t1 a, t2 b) 
    { 
     return (a + b); 
    }; 
+0

'std :: plus ' кто-нибудь? :) +1 –

+0

большое спасибо за ответ – osum

0

В вашем случае единственный способ для вызова функции будет adder1<int, double, int>(...).

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

adder(const t1& a, const t2&b, t3& result) 
0

Вы всегда возвращая int поэтому t3 не требуется. Вы можете изменить свой код, как:

template <typename t1, typename t2> 
int adder1 (t1 a , t2 b) 
    { 
     return int(a + b); 
    }; 


int main() 
{ 

     int sum = adder1(1,6.0); // error C2783 could not deduce template argument for t3 
     return 0; 

} 
3

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

template <typename t1, typename t2> 
int adder1 (t1 a , t2 b) 
{ 
    return int(a + b); 
}; 


int main() 
{ 
    int sum = adder1(1,6.0); // error C2783 could not deduce template argument for t3 
    return 0; 
} 
Смежные вопросы