【问题标题】:Passing a templated functor as an argument to a templated function in C++将模板化函子作为参数传递给 C++ 中的模板化函数
【发布时间】:2021-02-26 10:45:40
【问题描述】:

我正在尝试将模板化函子传递给模板化函数。 代码如下所示:

template<typename T>
T func_1(T &a) {
    return a;
}

template <typename T>
T test(T &a, std::function<T(T&)> &func){
    return func(a);
}

int main(){
    int a = 5;
    std::cout << test(a, func_1) << std::endl;
}

但是,我得到以下编译错误:

从''类型的右值对'std::function&'类型的非常量引用的初始化无效

如果我删除模板,代码就可以工作。有人可以帮我理解为什么吗?

【问题讨论】:

    标签: c++ templates functor


    【解决方案1】:

    func_1 是函数模板。你必须传递一个你希望这个函数被实例化的具体类型。在您的情况下,它是 inta 变量的类型。

    std::cout << test(a, func_1<decltype(a)>) << std::endl;
    

    然后,可以通过 func_1&lt;int&gt; 实例化创建 function 对象。这个函数是临时的,但是临时不能绑定到Lvalue引用,所以test的签名应该修改为接受const Lvalue ref:

    template <typename T>
    T test(T &a, const std::function<T(T&)> &func){
                 // <---- const 
        return func(a);
    }
    

    【讨论】:

    • 这太神奇了!谢谢你解释得这么好。
    【解决方案2】:

    问题在于func_1 只是一个模板,要获得函数指针,您首先需要一个函数(即函数模板的实例化)。

    您可以通过使func_1 成为一个不是模板本身的实际函子(即可调用对象)来获得您想要的:

    #include <functional>
    #include <iostream>
    
    struct func_1 {
        template <typename T>
        T operator()(T& a){ return a; }
    };
    
    template <typename T,typename F>
    T test(T &a, F func){
        return func(a);
    }
    
    int main(){
        int a = 5;
        std::cout << test(a, func_1{}) << std::endl;
                             //    ^^ create instance
    }
    

    “诀窍”是只有func_1::operator() 是一个模板,因此您可以创建func_1 的对象并在您知道T 实际上是什么之前传递它们。运算符仅在test 中调用而不是在main 中调用时才被实例化。

    【讨论】:

    • 这是@rafix07 解决方案的一个不错的替代方案。就我个人而言,我更喜欢使用他的方法。
    • @YashBansod 我也肯定更喜欢 rafix 的解决方案。我只是没有看到明显的。
    猜你喜欢
    • 2015-09-10
    • 2011-11-15
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    相关资源
    最近更新 更多