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

标签 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)"

知道这是为什么吗?

最佳答案

模板参数不能从函数的返回类型推导出来。您可以交换模板参数的顺序,以便能够对输入参数进行类型推导:

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/

相关文章:

c++ - 我的顶点法线应该是这样的吗?

c++ - 为什么我在为 vector <int> 实现这个简单的散列时出错?

c++ - 尽可能多地屏蔽 C++ 中的类实现

c++ - 我怎样才能让 g++ 模仿 MSVC++ 的模板实例化行为?

c++ - 我们可以给静态数组的大小一个变量吗

c++ - stderr 的奇怪行为

如果右手边包含字符串文字的串联,则 C++ const std::string 赋值错误

c++ - 如何在 std::vector 中找到项目的位置

c++ - C++ 中的全局变量和局部变量

c++ - 跨命名空间和不同 .H 文件的友元类