calling copy constructor with uniform initialization

Viewed 92

Im trying to call default copy constructor with uniform initialization, but it's not working.

For example:

#include <string>

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

int main() {
        Work s9 {"Beethoven", "Symphony No. 9 in D minor, Op. 125; Choral", 1824}; // memberwise initialization
        Work currently_playing {s9};    // copy initialization

        return 0;
}

Im compiling it as: g++ -std=c++11 -c Ex1.cpp

And compiler gives error:

Ex1.cpp: In function ‘int main()’:
Ex1.cpp:11:28: error: could not convert ‘s9’ from ‘Work’ to ‘std::string {aka std::basic_string<char>}’
  Work currently_playing {s9}; // copy initialization
                            ^

Doesn't uniform initialization work to copy initialize object?

2 Answers

This is a bug in the C++11 standard. C++14 changed how list-initialization is performed. In C++11, X{X{}} would perform aggregate-initialization if X is an aggregate type. C++14 added an extra clause so that this code correctly invokes the corresponding constructor; [dcl.init.list]/3.2:

If T is an aggregate class and the initializer list has a single element of type cv U, where U is T or a class derived from T, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization).

Sources:

http://eel.is/c++draft/dcl.init.list#3.2

http://en.cppreference.com/w/cpp/language/list_initialization#Explanation

Related