简体   繁体   English

将模板化仿函数作为参数传递给 C++ 中的模板化 function

[英]Passing a templated functor as an argument to a templated function in C++

I am trying to pass a templated functor into a templated function.我正在尝试将模板化函子传递给模板化 function。 The code looks something like this:代码看起来像这样:

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;
}

However, I get the following compile error:但是,我收到以下编译错误:

invalid initialization of non-const reference of type 'std::function<int(int&)>&' from an rvalue of type ''从 '' 类型的右值对类型 'std::function<int(int&)>&' 的非常量引用的无效初始化

The code works if I remove the template.如果我删除模板,代码就可以工作。 Can someone help me understand why?有人可以帮我理解为什么吗?

func_1 is function template. func_1是 function 模板。 You have to pass a concrete type you want this function to be instantiated.您必须传递一个您希望实例化此 function 的具体类型。 In your case it is int , type of a variable.在您的情况下,它是int ,变量a类型。

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

Then, function object can be created taking func_1<int> instantiation.然后,可以使用function func_1<int>实例化创建 function object。 This function is temporary, but temporary cannot be bound to Lvalue reference, so signature of test should be modified to accept const Lvalue ref:这个 function 是临时的,但临时不能绑定到Lvalue引用,所以应该修改test的签名以接受 const Lvalue ref:

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

The issue is that func_1 is just a template, to get a function pointer you first need a function (ie an instantiation of the function template).问题是func_1只是一个模板,要获得 function 指针,您首先需要一个 function (即 ZC1C425268E68385D1AB5074C17A94F14 模板的实例化)。

You can get what you want by making func_1 an actual functor (ie callable object) that is not a template itself:您可以通过使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
}

The "trick" is that only func_1::operator() is a template, so you can create objects of func_1 and pass them around before you know what T actually is. “诀窍”是只有func_1::operator()是模板,因此您可以创建func_1的对象并在您知道T实际是什么之前传递它们。 The operator is only instantiated when it is called in test but not in main .运算符仅在test而不是main中调用时才被实例化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM