2015-12-21 2 views
1

У меня есть два шаблона.Тип шаблона дедукции не работает в C++

Первый для целого

template <class T> 
T myMin(T a, T b) 
{ 
    return (a < b) ? a : b; 
} 

Второй один для строки

template <class TypeFrom, class TypeTo> 
TypeTo convert(TypeFrom &from) 
{ 
    return static_cast<TypeTo>(from); 
} 

template <> 
std::string convert<std::wstring, std::string>(std::wstring &from) 
{ 
    return std::string(from.begin(), from.end()); 
} 

Первый шаблон можно использовать без использования типов

int c = myMin(1,2); 

Но для второй шаблон Я должен использовать типы

std::string st = convert<std::wstring, std::string>(sw); 

я не могу использовать его без:

std::string st = convert(sw); // this fails with the error "no accordance found for convet<TypeFrom, TypeTo>(wstring)" 

Любая идея, почему это?

ответ

2

Аргумент шаблона не может быть выведен из возвращаемого типа функции. Вы можете поменять порядок вашего параметра шаблона, чтобы быть в состоянии сделать тип вычет входного аргумента (ы):

template <class TypeTo, class TypeFrom > 
TypeTo convert(TypeFrom &from) 
{ 
    return static_cast<TypeTo>(from); 
} 

template <> 
std::string convert<std::string, std::wstring>(std::wstring &from) 
{ 
    return std::string(from.begin(), from.end()); 
} 

// Partial deduction 
std::string st = convert<std::string>(sw); 

В принципе, вы не можете сделать convert(sw), потому что это может быть неоднозначным во многих случаях, например:

// Call without using the return value 
convert(sw); 

// Call with return value sent to an overloaded function 
void g (std::string) ; 
void g (int) ; 
g(convert(sw)); 

AFAIK, то же ограничение распространяется на перегруженную функцию (по той же причине). Вы не можете иметь в C++ (и на многих языках, таких как Java), следующие:

int f(); 
float f(); 

На самом деле, если вы думаете об этом, даже ваш вызов неоднозначен, поскольку std::string имеет несколько конструкторов, так что я должен делать:

std::string st = convert <std::string> (sw) ; // Copy constructor 
std::string st = convert <const char *> (sw) ; // Constructor from const char * 

Основная идея заключается в том, что, хотя она не может быть неоднозначной для вас (в то время как я хотел бы преобразовать в const char * вместо непосредственно std::string?), она неоднозначна для компилятора, и это не роль компилятора, чтобы сделать это вид выбора.

+0

Я вижу! Благодаря. Это означает, что я должен пропустить оператор = и использовать возвращаемый тип/значение в качестве другого параметра. –

+1

Всегда есть 'auto' (в C++ 11):' auto st = convert (sw); '. – CompuChip

+0

Есть ли веская причина, почему Бьярне Страуступ не считает тип возврата для вычета функции? –

Смежные вопросы