我有两个模板。
第一个为整数
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)"
知道这是为什么吗?
最佳答案
模板参数不能从函数的返回类型推导出来。您可以交换模板参数的顺序,以便能够对输入参数进行类型推导:
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));
据我所知,同样的限制适用于重载函数(出于同样的原因)。在 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
吗?),它对于编译器来说是模棱两可的,做出这种选择不是编译器的角色。
关于c++ - 模板类型推导在 C++ 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34391208/