C++14 中 lambda 的 std::result_of 限制
Limitations of std::result_of for lambdas in C++14
我有一段 C++17 代码,我想移植到 C++14(项目的约束)。该代码根据提供程序返回的 lambda 在堆上分配一个仿函数。
decltype(auto) fun_provider(std::string msg)
{
return [msg](){ std::cout << msg << std::endl; };
}
int main()
{
auto fun = std::make_unique<
std::invoke_result_t<decltype(fun_provider), std::string>
>(fun_provider("Provided functor"));
(*fun.get())()
}
// output: "Provided functor"
重点是,它避免了将 lambda 类型硬编码为 std::function<void()>
。据我所知,闭包类型是未指定的,这样的构造意味着闭包对象的不必要副本(希望这是正确的)。
我想用 C++14 实现同样的目标,有可能吗?我用 std::result_of
and/or decltype
尝试了一些构造,但到目前为止没有成功。
这个方法行不通吗?
auto fun = std::make_unique<
decltype(fun_provider(std::declval<std::string>()))
>(fun_provider("Provided functor"));
甚至没有必要使用 std::declval
; std::string{}
而不是 std::declval<std::string>()
就好了。
如何通过另一遍模板推导路由 fun_provider
的 return 值?
template <class T>
auto to_unique(T&& orig) {
using BaseType = std::remove_cv_t<std::remove_reference_t<T>>;
return std::make_unique<BaseType>(std::forward<T>(orig));
}
int main()
{
auto fun = to_unique(fun_provider("Provided functor"));
(*fun.get())();
}
只是为了完整性和回答原始问题。
使用 std::result_of_t
的正确解决方案如下所示:
auto fun = std::make_unique<
std::result_of_t<decltype(&fun_provider)(std::string)>
>(fun_provider("Provided functor"));
我有一段 C++17 代码,我想移植到 C++14(项目的约束)。该代码根据提供程序返回的 lambda 在堆上分配一个仿函数。
decltype(auto) fun_provider(std::string msg)
{
return [msg](){ std::cout << msg << std::endl; };
}
int main()
{
auto fun = std::make_unique<
std::invoke_result_t<decltype(fun_provider), std::string>
>(fun_provider("Provided functor"));
(*fun.get())()
}
// output: "Provided functor"
重点是,它避免了将 lambda 类型硬编码为 std::function<void()>
。据我所知,闭包类型是未指定的,这样的构造意味着闭包对象的不必要副本(希望这是正确的)。
我想用 C++14 实现同样的目标,有可能吗?我用 std::result_of
and/or decltype
尝试了一些构造,但到目前为止没有成功。
这个方法行不通吗?
auto fun = std::make_unique<
decltype(fun_provider(std::declval<std::string>()))
>(fun_provider("Provided functor"));
甚至没有必要使用 std::declval
; std::string{}
而不是 std::declval<std::string>()
就好了。
如何通过另一遍模板推导路由 fun_provider
的 return 值?
template <class T>
auto to_unique(T&& orig) {
using BaseType = std::remove_cv_t<std::remove_reference_t<T>>;
return std::make_unique<BaseType>(std::forward<T>(orig));
}
int main()
{
auto fun = to_unique(fun_provider("Provided functor"));
(*fun.get())();
}
只是为了完整性和回答原始问题。
使用 std::result_of_t
的正确解决方案如下所示:
auto fun = std::make_unique<
std::result_of_t<decltype(&fun_provider)(std::string)>
>(fun_provider("Provided functor"));