Home Uniform initialization on member initializer list error
Reply: 1

Uniform initialization on member initializer list error

Borja
1#
Borja Published in 2018-01-11 07:46:42Z

I am getting a compilation error on this C++11 code but I dont know why. This is the code:

#include <condition_variable>

class NonCopiableClass
{
    std::condition_variable condition_;
};

struct NonCopiableStruct
{
    std::condition_variable condition_;
};

class Test
{
 public:
    Test() : 
        myClass{},
        myStruct{}
    {};
 private:
    NonCopiableClass myClass;
    NonCopiableStruct myStruct;
};

Visual Studio 2015 fails with the following error:

error C2280: 'std::condition_variable::condition_variable(const std::condition_variable &)': attempting to reference a deleted function 1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\mutex(550): note: see declaration of 'std::condition_variable::condition_variable'

If I change the Test constructor to not use C++11 uniform initialization of the Struct it compiles OK.

Test() : 
        myClass{},
        myStruct() // <--- CHANGE
    {};

I am not getting why for Struct type uses copy constructor but the Class seems OK. It only happends with Struct having non copiable members.

I also noted that if I init the Struct outside of the Test Class member initializer list It works:

int main()
{
    NonCopiableStruct a{};   
    return 0;
}

Any idea Why is this code failing?. What is going on under the hood? What is the difference between myClass initialization and myStruct initialization?. Why it wont compile if used on the class member initializer list but it is OK it I use it outside?. I have tried on GCC and it seems to be OK.

Thanks in advance

StoryTeller
2#
StoryTeller Reply to 2018-01-11 07:52:47Z

This seems like a MSVC bug. The difference is that the struct version is an aggregate, and the class version is not (on account of the default private access specifier).

The class version is value initialized by {}. The struct version is aggregate initialized. A conforming compiler should just list initialize condition_ with {}, because you didn't provide an initializer for it.

But MSVC seems to be stumbling on the fact that members of an aggregate are copy initialized from the corresponding initializer in the initializer list. It seems to check for the copy c'tor, even if it isn't supposed to actually use it.

This is further supported by the fact it knows what to do when an object of the same type is initialized outside of a member initializer list.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.296666 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO