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

Fra*_*n V 4 c++ templates functor

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

例如,让我们定义一个类为

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

    T operator() (T valrhs){
        return value + valrhs; 
    }
};
Run Code Online (Sandbox Code Playgroud)

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

Add<double> add5 = Add<double>(5.0);
Run Code Online (Sandbox Code Playgroud)

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

template<typename T, typename Function> T doOperation (T data, Function f){
    return f(data);
}
Run Code Online (Sandbox Code Playgroud)

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

std::cout << doOperation(5.0, add5);
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢,任何帮助表示赞赏。

cig*_*ien 14

在这段代码中

std::cout << doOperation(5.0, add5);
Run Code Online (Sandbox Code Playgroud)

编译器执行函数模板参数推导

在这一行

Add<double> add5 = Add<double>(5.0);
Run Code Online (Sandbox Code Playgroud)

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

但是,从 c++17 开始,编译器将进行类模板参数推导,然后编译就好了

Add add5(5.0);
Run Code Online (Sandbox Code Playgroud)

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

template<typename T>  Add(T) -> Add<T>;
Run Code Online (Sandbox Code Playgroud)

附带说明一下,您的类Add看起来可以由返回 lambda 的函数模板替换。

template<typename T>
auto Add (T value) { 
    return [value] (T valrhs) { 
        return value + valrhs; 
    }; 
}
Run Code Online (Sandbox Code Playgroud)

用法看起来像

auto add5 = Add(5.0);
std::cout << doOperation(5.0, add5);
Run Code Online (Sandbox Code Playgroud)