为什么这些函数不衰减为函数指针?
Why don't these functions decay to a function pointer?
我有一个 class,它包含一个要调用的函数指针,现在我遇到了一种情况,我希望该可调用函数包含一个独立的 reference/value(拉姆达)。所以我创建了模板 class 来接受函数指针或 lambda,如下所示:
template <typename FunctionType>
class MyClass
{
public:
MyClass(FunctionType function) : function(function) {}
FunctionType function;
};
然而,似乎每次实例化此 class 时,编译器都会创建 class 的不同 'type',如下所示:
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';
}
这个输出是:
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)>
因为我将创建成百上千个这样的内容,所以我希望尽可能不要出现这种情况。我将传递给我的 class 的大多数函数应该是相同类型的,除了我需要的偶尔不同的 lambda。那么,每次我传递相同的函数类型时,编译器是否都会创建不同的类型?如果是这样的话,它似乎不是很有效。如果一定是这种情况,减少编译器创建的 class 类型数量的最佳方法是什么?我想我是通过在创建 class 时转换为函数指针来实现它的,但这似乎是一种糟糕的实现方式。
您可以让 class 存储一个函数指针,如下所示:
template <typename Ret, typename ...Args>
class MyClass
{
public:
MyClass(Ret (*function)(Args...)) : function(function) {}
Ret (*function)(Args...);
};
然后您可以通过将 lambda 显式衰减为函数指针来存储它:
MyClass foo( + []() {return 5; });
然后每个函数签名(无论是 lambda 还是函数)只会实例化一个 class。
这是一个demo。
我有一个 class,它包含一个要调用的函数指针,现在我遇到了一种情况,我希望该可调用函数包含一个独立的 reference/value(拉姆达)。所以我创建了模板 class 来接受函数指针或 lambda,如下所示:
template <typename FunctionType>
class MyClass
{
public:
MyClass(FunctionType function) : function(function) {}
FunctionType function;
};
然而,似乎每次实例化此 class 时,编译器都会创建 class 的不同 'type',如下所示:
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';
}
这个输出是:
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)>
因为我将创建成百上千个这样的内容,所以我希望尽可能不要出现这种情况。我将传递给我的 class 的大多数函数应该是相同类型的,除了我需要的偶尔不同的 lambda。那么,每次我传递相同的函数类型时,编译器是否都会创建不同的类型?如果是这样的话,它似乎不是很有效。如果一定是这种情况,减少编译器创建的 class 类型数量的最佳方法是什么?我想我是通过在创建 class 时转换为函数指针来实现它的,但这似乎是一种糟糕的实现方式。
您可以让 class 存储一个函数指针,如下所示:
template <typename Ret, typename ...Args>
class MyClass
{
public:
MyClass(Ret (*function)(Args...)) : function(function) {}
Ret (*function)(Args...);
};
然后您可以通过将 lambda 显式衰减为函数指针来存储它:
MyClass foo( + []() {return 5; });
然后每个函数签名(无论是 lambda 还是函数)只会实例化一个 class。
这是一个demo。