dru*_*rus 2 c++ lambda templates sfinae
我正在尝试实现类似的东西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
Run Code Online (Sandbox Code Playgroud)
问题是这个主题的延续.实施
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();
}
Run Code Online (Sandbox Code Playgroud)
如果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;
}
Run Code Online (Sandbox Code Playgroud)
但是如果lambda有参数,则std::result_of_t< Function() >需要传递参数列表以推导出lambda的结果类型(例如std::result_of_t< Function(int) >).
一种尺寸适合所有人.:-)
template <typename Function, typename... Args>
decltype(auto) Apply(Function&& func, Args&&... args) {
std::cout << "invoked" << std::endl;
return std::forward<Function>(func)(std::forward<Args>(args)...);
}
int main()
{
int i1 = Apply([]() { return 10; });
bool b1 = Apply([]( bool b) { return !b; }, true);
Apply([]() { return; });
std::cout << i1 << " " << b1 << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
或者,更好的是,只需使用std::invoke().
| 归档时间: |
|
| 查看次数: |
165 次 |
| 最近记录: |