#include <iostream>
#include <functional>
std::function<int(int)> makeLambda1(int x) {
return [x] (int y) { return x * y; };
}
auto makeLambda2(int x) {
return [x] (int y) { return x * y; };
}
auto makeLambda3() {
return [] (int y) { return 10 * y; };
}
int main() {
auto lambda1 = makeLambda1(10);
auto lambda2 = makeLambda2(10);
auto lambda3 = makeLambda3();
std::cout << sizeof(lambda1) << " ";
std::cout << sizeof(lambda2) << " ";
std::cout << sizeof(lambda3) << " ";
std::cout << sizeof(int(*)(int)) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出(https://ideone.com/ghoksF):
32 4 1 8
Run Code Online (Sandbox Code Playgroud)
Lambda 只是重载对象的语法糖operator()。这意味着
return [x] (int y) { return x * y; };
Run Code Online (Sandbox Code Playgroud)
相当于
class unique_unnamed_type
{
private:
const int x;
public:
unique_unnamed_type(int x) : x{x} {}
auto operator()(int y) { return x * y; } const
};
return unique_unnamed_type{x};
Run Code Online (Sandbox Code Playgroud)
仅从外观来看,您可能会猜测它sizeof(unique_unnamed_type)应该等于sizeof(int),因为它唯一的成员是一个int。
在非捕获情况下,等效对象仅略有不同。
return [] (int y) { return 10 * y; };
Run Code Online (Sandbox Code Playgroud)
相当于
class unique_unnamed_type
{
private:
using fp = int(*)(int);
static auto unnamed_static_function(int y) { return 10 * y; }
public:
auto operator()(int y) { return unnamed_static_function(y); } const
operator fp() { return unnamed_static_function; } const
};
return unique_unnamed_type{};
Run Code Online (Sandbox Code Playgroud)
这种类型的大小通常为1,就像任何没有成员的类类型一样(对象需要有一个唯一的地址,因此即使是“空”对象也会占用一个字节的存储空间,除非诸如空基优化之类的事情)。
值得注意的是,它比函数指针小,因为它不是函数指针。它只是一个带有隐式转换运算符的类,该运算符返回指向静态成员函数的指针。
std::function是一个完全不同的野兽。它是任何具有兼容签名的可调用类型的类型擦除容器。这种类型擦除有一些开销,因此std::function通常会比原始函数指针或 lambda 更大,但如果 lambda 捕获一个大对象,它可能会更小。对象引用的实际可调用std::function对象将动态分配,因此sizeof(std::function<int(int)>)不包括实际可调用对象的大小。
| 归档时间: |
|
| 查看次数: |
314 次 |
| 最近记录: |