error C2797 : list initialization inside member initializer list

前端 未结 3 1171
日久生厌
日久生厌 2021-01-14 10:22

I was watching MVA\'s tutorial on C++ and the code I\'m mentioning below is written by Kate not me. However she seems to get around with it without compiling showing any err

相关标签:
3条回答
  • 2021-01-14 10:43

    I solve it.

    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 İt can't initialize because variable can't find or load

    0 讨论(0)
  • 2021-01-14 10:55

    tl;dr: The solution in Kate's answer worked for the OP; the explanation is incorrect. The code in question is actually correct and does compile in VS2015. The error (in VS2013 Update 3) is a consequence of how MS handled a bug that was uncovered in VS2013 RTM (they didn't actually fix it with an 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 inserted these errors into the compiler in Update 3 because our implementation of non-static data member initialization was incomplete.

    List/braced initialization in a member initialization list is also broken in VS2013. The problem with their implementation is illustrated best with a vector, which has an initializer_list constructor that should greedily match any initialization that uses braces with convertable arguments, but it fails to do so:

    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 too readily falls back to normal overload resolution. Instead of using the std::initializer_list constructor, it calls the size_t constructor. As their comments indicate, this is wrong! So, because of their flawed implementation, Microsoft decided to disable the ability to use braced initialization in this context.

    For a std::string s, there should be no issue because the right thing for s{"duh"} is to call std::string(const char*), but because of the flaw, MS gives an error anyway. The workaround is to explicitly use parenthesis in place of braces (or upgrade to VS2015), as stated in Kate's answer. But the correct reason for the error is as stated above.

    This applies to Non-Static Data Member Initialization (NSDMI) as well as to initialization lists. This is explained more in this Visual C++ Team Blog. As for why VS2013 never got fixed:

    We originally planned to fix this bug in an update to Visual Studio 2013, but from an engineering perspective, the right thing to do is to avoid another kludge and thoroughly address the handling of initialization. But overhauling compiler architecture is a massive task due to the amount of fundamental code that needs to be modified. We could not risk creating incompatibilities or large bug tails in an update, so a correct implementation of NSDMI could only be shipped in a major release.

    Apparently, the fix made it into Visual Studio 2015, but will never be in an update to 2013.

    0 讨论(0)
  • 2021-01-14 11:02

    There was a compiler change between the time James and I wrote the code we used for the MVA day and today. What's happening is that

     _name{ initial_name }
    

    is being interpreted as creating an initializer-list with one item in it and using that to initialize the member variable. Which you can't do.

    The fix is to switch to round brackets:

     _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.

    0 讨论(0)
提交回复
热议问题