永远不会调用具有默认参数的复制构造函数

时间:2012-02-29 22:26:26

标签: c++ llvm clang copy-constructor

为什么以下程序的输出只是int3而不是int3&4

#include <iostream>

class B
{
public:
    explicit B(int i) { std::cout<<"int"<<i; }
    B(const B& rhs, int i = 0) { std::cout<<"&"<<i; }
};

int main(int, char**)
{
    B b(B(3), 4);
}

命令:clang++ test.cpp -O0

编译器:Apple clang 3.0版(标签/ Apple / clang-211.12)(基于LLVM 3.0svn)

3 个答案:

答案 0 :(得分:3)

看起来您可能找到了编译器怪癖:)

如果您将编译器版本更改为不是LLVM 3.0的任何内容,则输出为int3&amp; 4.

这在LLVm 3.0上打印int3&amp; 4,所以它似乎与B(3)是临时对象的事实有关:

class B
{
public:
    explicit B(int i)
    { 
        std::cout<<"int"<<i; 
    }
    B(const B& rhs, int i = 0) 
    { 
        std::cout<<"&"<<i; 
    }
};

int main(int, char**)
{
    B a(3);
    B b(a, 4);
}

答案 1 :(得分:1)

这是bug in clang,其中since been fixed。 Copy-elision被错误地应用于构造函数调用,因为在判断它是复制结构之前,clang没有检查提供了多少个参数。

修复将在即将发布的clang 3.1版本中发布。

答案 2 :(得分:0)

最有可能的是,RVO和NRVO吃了你的代码。这些特殊条件允许编译器以静默方式消除否则将由该语言强制执行的对象副本。由于结果没有复制,因此代码永远不会在复制构造函数中打印语句。