复制构造函数花括号初始化

9

"we can initializate objects of a class for which we have not define any constructor using:

  • memberwise initialization.
  • copy initialization.
  • default initialization.

For example:

    struct Work {
      string author;
      string name;
      int year;
    };

    Work s9 { "Bethoven",
              "Symphony No. 9 in D minor, Op. 125; Choral",
              1824
            };                    // memberwise initialization

    Work currently_playing {s9};  // copy initialization
    Work none {};                 // default initialization
《C++程序设计语言》第四版第17.3.1章节。
例如:
   struct Data
     {
        int mMember1;
        float mMember2;
        char mMember3;
     };

     int main()
     {
         Data aData_1{1,0.3,33};
         Data aData_2{aData_1};

         return EXIT_SUCCESS;
     }

尽管我无论使用GCC还是Clang都会遇到编译器错误,但这必须可行。在两个编译器中,错误信息都是“无法将Data转换为int”。然而,实现复制构造函数可以使此错误消失,或者使用圆括号语法而不实现它也可以。问题有点愚蠢,将花括号更改为圆括号即可解决问题。但是为什么没有遵循TC ++ PL的规则呢?这是编译器问题还是我误解了什么?提前致谢。


1
这个问题通过将代码修正为C++14版本来解决,请参考此链接 - M.M
1个回答

11
我认为这种行为符合8.5.4(列表初始化)第3句的规定:
列表初始化类型为T的对象或引用定义如下: - 如果T是一个聚合体,则执行聚合体初始化(8.5.1)。 - 其他情况下,如果初始化列表有一个类型为E的单个元素[...],则从该元素初始化对象或引用;
您原本期望适用于缩写引用中的第二项,但第一项具有优先权:由于Data确实是一个聚合体,因此永远不会考虑单元素列表条款。
你从书中引用的内容似乎是一个已知错误。据说这个问题将会在C++14中被修复以匹配书中的语言。

1
我已经编辑了你的回答中的消息,并将代码包含在书中。在这段代码中似乎应用了第二种行为。 - JoseLuis
@JoseLuis 这本书是完全错误的。括号初始化提案的作者可能本意是这样,但如果是这样,他们并没有成功地指定这一点。 - bames53
@JoseLuis:请查看C++14修正表,其中提到的勘误可能已得到修复。 - Kerrek SB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接