C++ 在可变模板中使用lambdas调用std::make_tuple-这在C++;11?
在C++11中,lambda函数是一个对象,应该可以用它调用make_tuple,对吗C++ 在可变模板中使用lambdas调用std::make_tuple-这在C++;11?,c++,c++11,tuples,variadic-templates,lambda,C++,C++11,Tuples,Variadic Templates,Lambda,在C++11中,lambda函数是一个对象,应该可以用它调用make_tuple,对吗 void foobar() { auto t = std::make_tuple([](){ std::make_shared<int>(); }); } void foobar(){ auto t=std::make_元组([](){std::make_shared();}); } 这个代码对我有用 现在,如果我们添加可变模板,会发生什么情况: #include <tuple&
void foobar() {
auto t = std::make_tuple([](){ std::make_shared<int>(); });
}
void foobar(){
auto t=std::make_元组([](){std::make_shared();});
}
这个代码对我有用
现在,如果我们添加可变模板,会发生什么情况:
#include <tuple>
#include <memory>
template <class... T>
void foobar() {
auto t = std::make_tuple([](){ std::make_shared<T>(); }...);
}
int main(int, char**)
{
foobar<int, float, double>();
return 0;
}
#包括
#包括
模板
void foobar(){
auto t=std::make_tuple([](){std::make_shared();};
}
int main(int,char**)
{
foobar();
返回0;
}
这一个未能在GCC 4.7.2中编译
main.cpp: In lambda function:
main.cpp:6:54: error: parameter packs not expanded with '...':
main.cpp:6:54: note: 'T'
main.cpp: In function 'void foobar()':
main.cpp:6:57: error: expansion pattern '#'lambda_expr' not supported by dump_expr#<expression error>' contains no argument packs
main.cpp: In instantiation of 'void foobar() [with T = {int, float, double}]':
main.cpp:11:29: required from here
main.cpp:在lambda函数中:
main.cpp:6:54:错误:参数包未扩展为“…”:
main.cpp:6:54:注:“T”
main.cpp:在函数“void foobar()”中:
main.cpp:6:57:错误:dump#u expr#不支持扩展模式“#”lambda_expr”不包含参数包
main.cpp:在“void foobar()[with T={int,float,double}]的实例化中:
main.cpp:11:29:从这里开始需要
我想知道,按照标准,这个代码正确吗?方法#1:
解决这个问题的简单方法似乎是std::function
:
#include <tuple>
#include <memory>
template <class T>
std::function<std::shared_ptr<T>()> make_shared_lambda() {
return [](){ return std::make_shared<T>(); };
}
template <class... T>
void foobar() {
auto factories = std::make_tuple(make_shared_lambda<T>()...);
auto tracer = std::get<2>(factories)();
}
// demonstration
#include <cstdio>
struct Tracer {
Tracer() { puts("Tracer()"); }
~Tracer() { puts("~Tracer()"); }
};
int main()
{
foobar<int, float, Tracer>();
}
方法2:
显然,std::function
的类型擦除存在性能开销。您可以轻松利用以下事实(标准5.1.2/6):
#包括
#包括
模板自动生成共享文件()->std::共享文件(*)()
{
return[](){return std::make_shared();};
}
模板std::tuple foobar(){
返回std::make_tuple(make_shared_f()…);
}
//示范
int main()
{
自动工厂=foobar();
自动双_ptr=std::get(factories)();
}
如果您的编译器支持模板别名,则可以使其不那么神秘:
template <typename T> using shared_factory = std::shared_ptr<T>(*)();
template <class T> shared_factory<T> make_shared_f() {
return []() { return std::make_shared<T>(); };
}
使用shared_factory=std::shared_ptr(*)的模板;
模板共享\u工厂制作\u共享\u f(){
return[](){return std::make_shared();};
}
这是gcc中的一个已知错误:(最初的示例是一个不同的模式,涵盖了参数包的捕获,但该模式和合并错误背后的问题是gcc根本没有实现lambdas和variadics的交集)
就标准而言,它是完全可以接受的代码。您的方法2似乎是错误的。OP的
foobar()
构造了一个“空函数的元组,每个都返回共享的\u ptr
”,但您的构造了一个“空函数,返回默认构造的共享的\u ptr
(?)”@KennyTM您似乎是对的。让我重写第二个:)我添加了一个更好的解决方法,而没有使用std::function
。
#include <tuple>
#include <memory>
template <class T> auto make_shared_f() -> std::shared_ptr<T>(*)()
{
return []() { return std::make_shared<T>(); };
}
template <class... T> std::tuple<std::shared_ptr<T>(*)()...> foobar() {
return std::make_tuple(make_shared_f<T>()...);
}
// demonstration
int main()
{
auto factories = foobar<int, float, double>();
auto double_ptr = std::get<2>(factories)();
}
template <typename T> using shared_factory = std::shared_ptr<T>(*)();
template <class T> shared_factory<T> make_shared_f() {
return []() { return std::make_shared<T>(); };
}