C++ 将 lambda 传递给模板参数 [英] C++ Pass lambda to template parameter

查看:59
本文介绍了C++ 将 lambda 传递给模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将 lambda 作为模板参数传递.
例如这段代码

How to pass lambda as template parameter.
For example this code

template<void (*callback)()>
void function() {
    callback();
}

int main() {
    function<[]() -> void { std::cout << "Hello world\n"; }>();
}

失败并显示错误'function' 的模板参数无效,需要编译时常量表达式".
我做错了什么.

fails with error "invalid template argument for 'function', expected compile-time constant expression".
What I'm doing wrong.

编辑
我想实现这样的东西

Edit
I want to implement something like this

template<typename T,
        T (*deserializer)(buffer *data),
        void (*serializer)(T item, buffer *data)>
class Type {
public:
    T item;

    Type(T item) : item(item) {
    }

    Type(buffer *data) {
        deserialize(data);
    }

    void serialize(buffer *data) {
        serializer(item, data);
    }

    void deserialize(buffer *data) {
        deserializer(data);
    }
};

typedef Type<int, [](buffer* data) -> int { return -1; }, [](int item, buffer* data) -> void {}> IntType

typedef Type<long, [](buffer* data) -> long { return -1; }, [](long item, buffer* data) -> void {}> LongType

推荐答案

C++14 中的 Lambda,包括它们到函数指针的转换,都不是 constexpr.

Lambdas in C++14, including their conversion to function pointers, are not constexpr.

在 C++17 中,这是会改变.据我所知,目前还没有实现该功能的稳定编译器(如果您找到了,能否在下面的评论中提及?).

In C++17, this is going to change. There are no stable compilers with that feature implemented that I'm aware of (if you find one, can you mention it in the comments below?).

那个时候

constexpr auto tmp = []() -> void { std::cout << "Hello world\n"; };
function<+tmp>();

肯定会起作用.我不确定

will definitely work. I am uncertain if

function<+[]() -> void { std::cout << "Hello world\n"; }>()

会起作用;在未求值的上下文和模板参数列表中,有一些关于 lambda 的规则可能与 constexpr lambda 问题不同,可能适用于此处.

would work; there are some rules about lambdas in unevaluated contexts and inside template argument lists that may be separate from the constexpr lambda problem and may apply here.

我们可以用 C++14 破解它.

We can hack it in C++14.

创建一个模板类,用于存储 lambda 的静态副本并公开具有相同签名 (f_ptr) 的静态函数,该函数调用该 lambda 的静态副本.

Create a template class that stores a static copy of a lambda and exposes a static function with the same signature (f_ptr) that calls that static copy of a lambda.

使用您的 lambda 全局实例化一次.

Instantiate it once globally with your lambda.

将指向 f_ptr 的指针传递给您的模板.

Pass a pointer to the f_ptr to your template.

所以:

template<class L> struct stateless; // todo
template<class L> stateless<L> make_stateless(L l){return std::move(l);}

auto foo = make_stateless( []() -> void { std::cout << "Hello world\n"; } );

function< &foo::f_ptr >();

这几乎肯定不是您想要的.

this is almost certainly not what you want.

这篇关于C++ 将 lambda 传递给模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆