【发布时间】:2018-01-31 11:25:22
【问题描述】:
我正在尝试实现类似于boost::static_visitor 的东西,具有接受 lambda 并支持以下 API 的模板函数:
int i1 = Apply([](int i) { return i; }); // doesn't compile
int i2 = Apply([]() { return 10; }); // ok
bool b1 = Apply([]() { return true; }); // ok
Apply([]() { return; }); // ok
问题是this topic 的延续。 实现
template <typename Function, typename Return = std::result_of_t<Function()>,
typename = typename std::enable_if<!std::is_same<Return, void>::value>::type>
Return Apply(Function func)
{
std::cout << "invoked via Return(*)(...)" << std::endl;
return func();
}
template <typename Function, typename Return = std::result_of_t<Function()>,
typename = typename std::enable_if<std::is_same<Return, void>::value>::type>
void Apply(Function func)
{
std::cout << "invoked via void(*)(...)" << std::endl;
func();
}
如果 lambda 没有参数也可以正常工作
#include <functional>
#include <type_traits>
#include <iostream>
template <typename Function, typename Return = std::result_of_t<Function()>, typename = typename std::enable_if<!std::is_same<Return, void>::value>::type>
Return Apply(Function func)
{
std::cout << "invoked via Return(*)(...)" << std::endl;
return func();
}
template <typename Function, typename Return = std::result_of_t<Function()>, typename = typename std::enable_if<std::is_same<Return, void>::value>::type>
void Apply(Function func)
{
std::cout << "invoked via void(*)(...)" << std::endl;
func();
}
int main()
{
int i1 = Apply([]() { return 10; });
bool b1 = Apply([]() { return true; });
Apply([]() { return; });
std::cout << i1 << " " << b1 << std::endl;
return 0;
}
但如果 lambda 有参数,std::result_of_t< Function() > 需要传递参数列表来推断 lambda 的结果类型(例如std::result_of_t< Function(int) >)。
【问题讨论】:
-
只是眯着眼睛我在想可变参数模板。请发一个minimal reproducible example,在无参数情况下编译运行。
-
问题中的链接是禁止的。
-
@JiveDadson:这不是真的。但是,您的编辑是正确的——不要链接到小代码 sn-ps;它们属于内联。
-
嘿,@drus,给答案打一个绿色复选标记怎么样?
-
Jive,恐怕没有一个解决方案能满足我的需要。我暂时停止使用没有参数的 lambda。
标签: c++ templates lambda sfinae