显式复制构造函数行为和实际用途

ice*_*ime 38 c++

最近的一个问题让我想知道显式复制构造函数.这是我在Visual Studio 2005下尝试编译的示例代码:

struct A
{
    A() {}
    explicit A(const A &) {}
};

// #1 > Compilation error (expected behavior)
A retByValue()
{
    return A();
}

// #2 > Compiles just fine, but why ?
void passByValue(A a)
{
}

int main()
{
    A a;
    A b(a); // #3 > explicit copy construction : OK (expected behavior)
    A c = a; // #4 > implicit copy construction : KO (expected behavior)

    // Added after multiple comments : not an error according to VS 2005.
    passByValue(a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在提问:

  • 标准是否允许#2?如果是,那么描述这种情况的相关部分是什么?
  • 您是否知道显式复制构造函数的任何实际用途?

[编辑]我刚刚在MSDN上找到了一个有趣的链接,具有完全相同的情况,以及主要功能的一个神秘评论:"c被复制"(好像很明显).正如Oli Charlesworth所指出的那样:gcc没有编译这段代码,我相信他是不对的.

out*_*tis 41

我相信C++ 03的相关部分是§12.3.12:

一个明确的构造函数构造对象一样,不明确的构造函数,但这样做只会在直接初始化语法(8.5),或在铸件(5.2.9,5.4)明确地使用.默认构造函数可以是显式构造函数; 这样的构造函数将用于执行默认初始化或值初始化(8.5).

§8.512:

参数传递,函数返回,抛出异常(15.1),处理异常(15.3)和大括号括起初始化列表(8.5.1)时发生的初始化称为复制初始化,相当于表单

    T x = a;
Run Code Online (Sandbox Code Playgroud)

新表达式(5.3.4),static_cast表达式(5.2.9),功能表示法类型转换(5.2.3)以及基本和成员初始化程序(12.6.2)中发生的初始化称为直接初始化,相当于表格

    T x(a);
Run Code Online (Sandbox Code Playgroud)

passByValue(a)根据C++03§12.3.12,调用涉及复制初始化,而不是直接初始化,因此应该是错误.

  • 虽然MSalters和Oli的答案是正确的,但我会接受这个,因为它清楚地表明VS是错误的.谢谢 ! (2认同)

MSa*_*ers 5

定义passByValue是可以的,因为没有复制A对象的语句.在定义中retByValue当然有一个复制A对象的return语句.