简体   繁体   中英

Why doesn't Constructor/virtual destructor with braced initializer list work?

Why doesnt the following code compile?

#include <vector>

class Foo
{
public:
    Foo()
    { }

    virtual ~Foo()
    { }

    std::vector<int> aVec;
};


Foo bar =
{
    { 1, 2, 3, 4, 5 }
};

While following code compiles:

#include <vector>

class Foo
{
public:

    /*Foo()
    { }

    virtual*/ ~Foo()
    { }

    std::vector<int> aVec;
};


Foo bar =
{
    { 1, 2, 3, 4, 5 }
};

Along with the reference to language rules, please elaborate on the rationale behind those rules.

Why does the existence of contructor and virtual destructor stops from initializing?

Because Foo is of class type, such that the braced init list is seen as an aggregate initialization . This requires, among others, that the class does not have explicit constructors or virtual members:

Aggregate initialization is a form of list-initialization, which initializes aggregates. An aggregate is one of the following types:

class type (typically, struct or union), that has...

  • no private or protected non-static data members

  • no user-provided, inherited, or explicit (since C++17) constructors (explicitly defaulted or deleted constructors are allowed)

  • no virtual, private, or protected base classes
  • no virtual member functions
  • default member initializers

The form of list initialization you are using is known as aggregate initialization . It's used for aggregate type. One of the requirements for a type to qualify as an aggregate is that it has no user provided constructors.

By providing a constructor, the compiler will try to match the list initialization to one of the defined constructors. It will prefer a constructor taking a single std::initializer_list . Since you do not provide one, it will try to find a constructor whos arguments match those provided by your initialization list. Since the only constructor is the default constructor which takes no arguments, no match is found.

Foo bar = { { 1, 2, 3, 4, 5 } }; is aggregate initialization . It is only defined for arrays and "aggregate" class types. Adding any constructor or virtual member means the type is not aggregate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM