2
votes

Brace initialization

        struct A
        {
            int a;
            int b;
            void foo(){}
        };

        A a{1, 2};

It works fine. But if change foo to a virtual function, It will not compile with error,

Error C2440 'initializing': cannot convert from 'initializer list' to

I find this,

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

But what's the reason behind it?

1
I may be totally wrong, but I know some of the things mentioned in the link you posted, like virtual methods, private or protected non-statics, base classes, ... could (or really 100% do) change the layout of the objects in memory (addition of a vptr, privates and protected could potentially be rearranged by the compiler - any of these would also break std::is_standard_layout<T>. So maybe this wouldn't allow aggregates to work as expected. The user provided constructor is another story - to me it's about how to choose between it and an aggregate init. You can add a ctor with initializer_listben10

1 Answers

0
votes

Why don't you use a parameterized constructor with virtual void foo() {}

struct A
{
    int a;
    int b;
    A(int a, int b)
    {
        this->a = a;
        this->b = b;
    }
    virtual void foo() {}
};
A a{ 1, 2 };