我一直在查看GCC实现的std::function
(在调试时进入并偏离了主题)。
据我所见,它会将小类型存储在本地存储器中,而任何不适合本地存储器的内容都会通过新操作符分配。但是构造函数也会检查__location_invariant
元函数,它是std::trivially_copyable
特性的包装器,如果它不是“位置不变量”,还会在堆上进行分配。
我不完全明白为什么要这样做,因为据我所知,::new(storage)T(args)
应该与new T(args)
提供相同的结果。唯一的例外是就地构造函数不会分配任何内存。
如果它,例如,使用单个引用计数对象来存储太大而无法适应本地存储器的“位置不变量”类型,那么这将减少分配和复制的数量。对于非不变量对象,每次都要分配和复制,因为它们是“位置相关”的,不能全部引用同一存储区域。
实现似乎只对任何不适合或不是位置不变量的内容进行堆分配(至少我没有看到它这样做?),所以我很困惑它为什么需要检查位置不变性,如果在功能上没有明显的区别。