模板类型推导在C++中不起作用

Template type deduction not working in C++

本文关键字:C++ 不起作用 类型      更新时间:2023-10-16

我有两个模板。

整数的第一个

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));

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吗?),但对编译器来说是模糊的,编译器角色不能做出这种选择。