如果类没有任何成员变量,则通过临时对象调用类的成员函数的开销是多少?
What is the cost of calling a member function of a class through a temporary object if the class doesn't have any member variables?
i最近正在研究ENTT库的源代码,我遇到了类似于以下代码片段的内容(请注意,我对我的问题进行了大量简化的简化(:
// Note that this class doesn't contain any member variables
class TextureLoader
{
public:
TextureLoader() = default;
~TextureLoader() = default;
std::shared_ptr<Texture> loadResource(const std::string& textureFilePath) const;
};
template<typename TResource, typename TResourceLoader, typename... Args>
std::shared_ptr<TResource> loadResource(Args&&... args)
{
// Note how a temporary TResourceLoader is created to invoke its loadResource member function
return TResourceLoader{}.loadResource(std::forward<Args>(args)...));
}
int main()
{
std::string texFilePath = "tex.png";
std::shared_ptr<Texture> myTexture = loadResource<Texture, TextureLoader>(texFilePath);
return 0;
}
您可以看到,loadResource
功能模板能够加载任何资源类型(例如Texture
,Shader
,Model
,Sound
等(。图书馆的文档指出,装载机类理想情况下应不包含任何成员变量。我想这是因为每次称为loadResource
时,都会创建加载程序类的临时性来调用其loadResource
成员函数。这就是我的问题所在:TResourceLoader{}.loadResource()
的成本是多少?编译器是否能够删除临时性的创建,因为它不包含任何成员变量?有更好的方法吗?
应该没有显着的性能含义,尽管代码会受到稍微惩罚。为了更好地理解含义,让我们尝试将代码分解为类似于编译器生成的代码的事物:
来自:
return TResourceLoader{}.loadResource(std::forward<Args>(args)...));
to:
char Storage[1]; // Any object in C++ is at least 1 byte, including classes with no members
Storage(&Storage); // Pseudo-code illustrating calling constructor
loadResource(&Storage, <args>); // considering loadResource can't be inlined
Storage.~Storage();
在上面的代码中,编译器将看到构造函数和驱动器都是默认器,并且由于类的确没有成员,因此可以安全地省略这些成员。
。您最终的结果是必须在自动存储中分配1个字节,在现代体系结构上通常意味着减少堆栈指针寄存器,然后通过增加。
这是非常快的操作,但仍然不是瞬时。
是的,编译器将优化没有任何数据成员的临时变量的创建。基本上不需要代码。您可以自己验证它,并在Compiler Explorer等在线工具上使用各种优化级别。
相关文章:
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法