C++ 什么时候需要模板参数?

When are template arguments required in C++?

我很好奇 C++ 中何时需要模板参数。

例如,我们定义一个class为

template<typename T> class Add {
    T value;
public:
    Add(T value) : value(value){};

    T operator() (T valrhs){
        return value + valrhs; 
    }
};

如果我们想使用 double 创建一个 Add 类型的对象,我们需要按如下方式定义它以避免出错,

Add<double> add5 = Add<double>(5.0);

现在让我们考虑一个定义如下的函数,

template<typename T, typename Function> T doOperation (T data, Function f){
    return f(data);
}

在代码中,如果要调用 doOperation,则不需要模板参数。例如,

std::cout << doOperation(5.0, add5);

会输出10。为什么doOperation不需要模板参数,而定义add5需要模板参数?

另外,有什么方法可以使用函数指针来定义它。我一直在试图弄清楚如何使用函数指针作为参数变量而不是第二个模板参数来传递这样的仿函数。

谢谢,如有任何帮助,我们将不胜感激。

在此代码中

std::cout << doOperation(5.0, add5);

编译器 function-template argument deduction.

在这一行

Add<double> add5 = Add<double>(5.0);

您需要提供模板参数,因为编译器不会执行 class-模板参数推导。

但是,从 c++17 开始,编译器会执行 class-template argument deduction,然后编译就可以了

Add add5(5.0);

您也可以明确提供推导指南,因为在某些情况下可能需要

template<typename T>  Add(T) -> Add<T>;

附带说明一下,您的 class Add 看起来可以用 returns lambda 的函数模板替换。

template<typename T>
auto Add (T value) { 
    return [value] (T valrhs) { 
        return value + valrhs; 
    }; 
}

用法看起来像

auto add5 = Add(5.0);
std::cout << doOperation(5.0, add5);

When are template arguments required in C++?

当无法推导模板参数时,必须显式提供模板参数 - 除非参数具有默认参数。

函数模板的模板参数可以从非模板参数推导出来。如果模板 class 具有推导指南(可能隐式生成),则 class 模板的模板参数可以从构造函数的参数推导出来。

Why is it that doOperation does not require template arguments

因为模板参数是从data的非模板参数推导出来的。

but the defining add5 required template arguments?

实际上,add5 不需要显式模板参数。以下将起作用:

Add add5(5.0);

...除非您使用没有模板推导指南(在 C++17 中引入)的旧版本 C++。

自 C++17 以来,有一个 class-模板参数推导,如上所述。 但是你一定要稳住,因为它可能会产生你不想要的结果。

Add a(5.0); // the type Add<double> is deduced

Add b(5); // the type Add<int> is deduced, which may be unwanted, if you need Add<double> 
          // if so you must specify the desired type