c++ - 什么时候需要指定模板的类型

标签 c++ templates function-templates

我编写了一个简单的模板来查找参数列表中的最小数字。

template<typename T>
T smallerList(T a, T b) {
    std::cout << "a= " << a << " b= " << b << std::endl;
    return a < b ? a : b;
}

template<typename T, typename... Rest>
T smallerList(const T& param0, const Rest&... rest) {
    T temp =  smallerList(rest...);
    return param0 < temp ? param0 : temp;
}

int main()
{
       // Works, returns "3"
       std::cout << "Smaller: " << smallerList(4, 5, 6, 3, 7) << std::endl;

       // Sort of works, returns "2". Should be "2.14".
       std::cout << "Smaller: " << smallerList(3.14, 43534, 100.2, 3.13, 2.14) << std::endl; 

}

出于某种原因,第二个函数调用返回 2 而不是 2.14。为什么会这样?

我已经打印了变量的中间值,它们是正确的。当 smallerList 返回时,似乎正在发生隐式转换。

我可以通过改变线路来解决这个问题

T temp =  smallerList(rest...);

进入

T temp =  smallerList<T>(rest...);

此更改后,函数按预期打印 2.14。

我的问题:为什么需要指定类型?我认为模板函数是为调用的每种类型“创建”的?

最佳答案

好吧,我不知道如何真正帮助你,因为我不知道你想要的确切逻辑是什么。但是在你的可变参数模板中你允许类型混合,并且在你的第二个 vector 中,你传递一个整数 - 43534 ,所以当2.14当递归回滚时反向传播你得到类似的东西

return (int)(43534 < 2.14? 43534 : 2.14);

因为 43534将是 param0 ,然后您采用 param0 的返回类型, 和 2.14转换为 2 .接下来它被转换回 float但你看不到它。

你要么需要检查参数的类型是否相同,要么想出一些逻辑来促进你的论点。并不是说如果您使用 43534.0 它确实会像您期望的那样工作因为它不会是 int不再。

编辑:

T temp = smallerList<T>(rest...);这并没有真正帮助你,它改变了行为,强制将每个参数强制转换为第一个参数的类型。好吧,它变得更加一致。但是尝试:

smallerList(7, 10.5, 10, 3.13, 2.14)

它会破裂。我不是 100% 确定为什么,但我猜它无法匹配递归结束,因为它会寻找 smallerList(int, float)并且您的终结器模板将不匹配。

你需要这样的东西:

template<typename T, typename U>
T smallerList(T a, U b) {
    std::cout << "a= " << a << " b= " << b << std::endl;
    return a < b ? a : b;
}

它还会丢弃第二个类型,因此您将进行类型转换,但如果您的目标是保持第一个参数的类型,则它是一致的。

关于c++ - 什么时候需要指定模板的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37607579/

相关文章:

c++ - 如何: variadic wrapper function that catches exceptions of input function

c++ - 非尾随函数模板参数包的合法使用?

c++ - 成员函数模板放在哪里

C++:指向不相关结构内的类成员函数的指针

c++ - 从 C 代码库在 C++ 中对 unsigned char * 上的 strchr 进行微创更改?

c++ - 如何创建一个变量模板?

c++ - 不同类型的特化

c++ - 为什么ostream_iterator需要显式声明要输出的对象类型?

c++ - 我刚刚制作的程序显然是病毒? C++

html - 是我的 HTML "leaking",因为它显示异常行为