Zeb*_*ish 1 c++ lambda templates closures
我有一个包含要调用的函数指针的类,现在我遇到了一种情况,我希望该可调用函数包含一个自包含的引用/值 (lambda)。所以我创建了我的模板化类来接受这样的函数指针或 lambdas:
template <typename FunctionType>
class MyClass
{
public:
MyClass(FunctionType function) : function(function) {}
FunctionType function;
};
Run Code Online (Sandbox Code Playgroud)
然而,似乎每次实例化这个类时,编译器都会创建一个不同的“类型”类,如下所示:
int main()
{
MyClass foo([]() {return 5; });
MyClass foo2([]() {return 5; });
MyClass foo3([]() {return 5; }); // ALL THREE OF THESE SEEM TO BE DIFFERENT TYPES
MyClass foo4(static_cast<int(*)()> ([]() {return 5; })); // I THINK I CAN FORCE THEM TO BE THE SAME TYPES BY CASTING
MyClass foo5(static_cast<int(*)()> ([]() {return 5; }));
MyClass foo6(static_cast<int(*)()> ([]() {return 5; }));
std::cout << typeid(foo).name() << '\n';
std::cout << typeid(foo2).name() << '\n';
std::cout << typeid(foo3).name() << '\n';
std::cout << typeid(foo4).name() << '\n';
std::cout << typeid(foo5).name() << '\n';
std::cout << typeid(foo6).name() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
输出结果是:
class MyClass<class <lambda_e39b14fd1b959adc3c33a259b5258211> >
class MyClass<class <lambda_de164f9f0bca248459ade49332a364c3> >
class MyClass<class <lambda_9fcf071b66983e924cb117ca1e77c4c6> >
class MyClass<int (__cdecl*)(void)>
class MyClass<int (__cdecl*)(void)>
class MyClass<int (__cdecl*)(void)>
Run Code Online (Sandbox Code Playgroud)
由于我将创建成百上千的这些,如果可能的话,我希望情况并非如此。我将传递给我的类的大多数函数应该是相同的类型,除了我偶尔需要的不同 lambda。那么每次我传递相同的函数类型时,编译器是否都会创建不同的类型?如果是这样的话,似乎效率不高。如果必须是这种情况,减少编译器创建的类类型数量的最佳方法是什么?我想我是通过在创建类时强制转换为函数指针来实现的,但这似乎是一种糟糕的做法。
你可以让你的类存储一个函数指针,就像这样:
template <typename Ret, typename ...Args>
class MyClass
{
public:
MyClass(Ret (*function)(Args...)) : function(function) {}
Ret (*function)(Args...);
};
Run Code Online (Sandbox Code Playgroud)
然后您可以存储 lambda,通过将其显式衰减为函数指针:
MyClass foo( + []() {return 5; });
Run Code Online (Sandbox Code Playgroud)
然后每个函数签名只会实例化一个类(无论是 lambda 还是函数)。
这是一个演示。