调用空类的构造函数实际上是否使用任何内存?

Vic*_*Liu 9 c++ templates metaprogramming micro-optimization

假设我有类似的课程

class Empty{
    Empty(int a){ cout << a; }
}
Run Code Online (Sandbox Code Playgroud)

然后我用它来调用它

int main(){
    Empty(2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是否会导致在堆栈上分配任何内存以创建"空"对象?显然,参数需要被推入堆栈,但我不想产生任何额外的开销.基本上我使用构造函数作为静态成员.

我想这样做的原因是因为模板.实际的代码看起来像

template <int which>
class FuncName{
    template <class T>
    FuncName(const T &value){
        if(which == 1){
            // specific behavior
        }else if(which == 2){
            // other specific behavior
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

这让我可以写出像

int main(){
    int a = 1;
    FuncName<1>(a);
}
Run Code Online (Sandbox Code Playgroud)

这样我就可以专门化一个模板参数,而不必指定类型T.此外,我希望编译器将优化构造函数内的其他分支.如果有人知道这是真的还是如何检查,那将非常感激.我还假设投掷模板进入情况不会改变上面的"空类"问题,是吗?

Ric*_*ton 17

引用Stroustrup:

为什么空类的大小不为零?确保两个不同对象的地址不同.出于同样的原因,"new"总是返回指向不同对象的指针.考虑:

class Empty { };

void f()
{
    Empty a, b;
    if (&a == &b) cout << "impossible: report error to compiler supplier";

    Empty* p1 = new Empty;
    Empty* p2 = new Empty;
    if (p1 == p2) cout << "impossible: report error to compiler supplier";
}   
Run Code Online (Sandbox Code Playgroud)

有一条有趣的规则表明空基类不需要用单独的字节表示:

struct X : Empty {
    int a;
    // ...
};

void f(X* p)
{
    void* p1 = p;
    void* p2 = &p->a;
    if (p1 == p2) cout << "nice: good optimizer";
}
Run Code Online (Sandbox Code Playgroud)

这种优化是安全的,并且是最有用的.它允许程序员使用空类来表示非常简单的概念而不会产生开销.一些当前的编译器提供了这种"空基类优化".