C++ 将 lambda 传递给模板参数 [英] C++ Pass lambda to template parameter
问题描述
如何将 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屋!