Error C2797: Initializing a list inside a member initializer list

I was looking at the MVA C ++ tutorial , and the code I mention below was not written by me by Keith. However, she seemed to get around it without compiling, showing any error, but in my case I get the following error:

Error 1 error C2797: 'NamedRectangle :: _ name': list initialization internal member initializer list or non-static data initializer not implemented c: \ users \ abhimanyuaryan \ documents \ visual studio 2013 \ projects \ kate demos \ 17 inheritance \ inheritance \ namedrectangle. h 12 1 Inheritance

Line 12 in the code belongs to my class NameRectangle

, which inherits from the class Rectangle

:

class NamedRectangle :  public Rectangle
{
public:
    NamedRectangle() { }

    NamedRectangle(std::string initial_name, int initial_width, int initial_height)
        : Rectangle{ initial_width, initial_height }, _name{ initial_name } //--> This line
    {}  

std::string get_name() const { return _name; }

private:
    std::string _name;

};

      

when i remove std::string

initial_name from constructor and also _name{initial_name}

compiles the code. Please explain to me without taking me as an experienced programmer with a higher standard. I started C ++ yesterday.

+3


source to share


3 answers


Between James and I, the code was written that we have used for MVA day and today. What's going on what

 _name{ initial_name }

      

is interpreted as creating an initializer list with one element in it and using that to initialize a member variable. That you can not do.



The fix is ​​to switch to parentheses:

 _name(initial_name)

      

This is causing confusion for a number of people, and I have at least one client for whom this broke working code.

+7


source


tl; dr : The solution in Keith's answer worked for the OP; the explanation is incorrect. This code is indeed correct and compiles in VS2015. The bug (in VS2013 Update 3) is a consequence of how MS handled a bug that was discovered in the RTM of VS2013 (they didn't actually fix it with the update, but they did break some working code). It is fixed correctly in VS2015.


Your code works fine in VS2015. According to Microsoft , in VS2013,

Yes, we introduced these errors into the compiler in Update 3 because our implementation of non-static member initialization was incomplete.

List / copied initialization in member initialization list is also broken in VS2013. The problem with their implementation is best illustrated with vector

, which has a constructor initializer_list

that should eagerly match any initialization that uses parentheses with convertible arguments, but that fails:

struct S {
    S() : v1{1} {} // C2797, VS2013 RTM incorrectly calls 'vector(size_type)'

    std::vector<int> v1;
    std::vector<int> v2{1, 2}; // C2797, VS2013 RTM incorrectly calls 
                               // 'vector(size_type, const int &)'
};

      



The compiler falls back too easily to normal overload resolution. Instead of using a constructor, std::initializer_list

it calls the constructor size_t

. As their comments show, this is wrong! So, due to its flawed implementation, Microsoft decided to disable the ability to use forced initialization in this context.

There std::string s

shouldn't be any problem for a, because for s{"duh"}

< needs to be called std::string(const char*)

, but due to a flaw in MS it still gives an error. A workaround is to explicitly use braces instead of braces (or upgrade to VS2015) as pointed out in Keith's answer. But the correct reason for the error is as stated above.

This applies to initialization of non-static data items (NSDMI) as well as initialization lists. This is explained in this Visual C ++ Team Blog . As for why VS2013 never got fixed:

We originally planned to fix this bug when upgrading to Visual Studio 2013, but from an engineering point of view, the right thing to do is avoid the other kludge and handle initialization handling carefully. But rebuilding the compiler architecture is a huge task because of the amount of fundamental code that needs to be changed. We couldn't risk creating incompatibilities or big tails of bugs in the upgrade, so the correct NSDMI implementation can only be submitted in the major release.

Apparently the fix made it to Visual Studio 2015, but will never be updated until 2013.

+11


source


I solve this.

class Namedrectangle : public Rectan
{
    public:
    Namedrectangle(){}

    Namedrectangle(string intname, int init_width, int init_height) 
         : Rectan{ init_width, init_height }
    {
        this->_name=intname;************
    }

    string get_name() const
    {
        return _name;
    }

    private:
    string _name;
};

      

I think it cannot be initialized because the variable cannot find or load

-4


source







All Articles