Should this code fail to compile in C++17?

前端 未结 1 2019
故里飘歌
故里飘歌 2021-01-01 08:44

I was updating a project to use C++17 and found a few instances where code that followed this pattern was causing a compile error on recent versions of clang:



        
相关标签:
1条回答
  • 2021-01-01 08:53

    clang is correct here. Here's a reduced example:

    struct B {
    protected:
        B() { }
    };
    
    struct D : B { };
    
    auto d = D{};
    

    In C++14, D is not an aggregate because it has a base class, so D{} is "normal" (non-aggregate) initialization which invokes D's default constructor, which in turn invokes B's default constructor. This is fine, because D has access to B's default constructor.

    In C++17, the definition of aggregate was widened - base classes are now allowed (as long as they're non-virtual). D is now an aggregate, which means that D{} is aggregate initialization. And in aggregate-initialization, this means that we (the caller) are initializing all the subobjects - including the base class subobject. But we do not have access to B's constructor (it is protected), so we cannot invoke it, so it is ill-formed.


    Fear not, the fix is easy. Use parentheses:

    auto d = D();
    

    This goes back to invoking D's default constructor as before.

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