5

I try to understand the first accepted answer of @bolov to the question Deleted default constructor. Objects can still be created... sometimes [1]

It seems like I found a error there and so it messes up the whole explanation.

@bolov explains why this code SUCCEED to be compiled in c++11:

Scenario A

struct foo {
  foo() = delete;
};

// All bellow OK (no errors, no warnings)
foo f = foo{};
foo f = {};
foo f{}; // will use only this from now on.

And why this code FAILS to be compiled in c++11:

Scenario C

struct foo {
  foo() = delete;
  foo(int) {};
};

foo f{}; // error call to deleted constructor

He says that the point is that the first one foo is an aggregate and the second one foo is not an aggregate.

Then he gives the excerpt from cppreference:

The effects of list initialization of an object of type T are: ...

  • If T is an aggregate type, aggregate initialization is performed. This takes care of scenarios A B D E (and F in C++14)
  • Otherwise the constructors of T are considered in two phases:

    • All constructors that take std::initializer_list ...

    • otherwise [...] all constructors of T participate in overload resolution [...] This takes care of C (and F in C++11) ...

According to the excerpt when you write foo f { }; in scenario A you get aggregate-initialization. An it would be great. But in reality in c++11 (#3337 draft, closest to standard) you have different initialization order:

List-initialization of an object or reference of type T is defined as follows:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1)

So foo f { }; in scenario A should result in value-initialization, that is, the DELETED default constructor will be called and the code should fail to be compiled.

6
  • 2
    I have no idea what you're asking. Commented Sep 20, 2016 at 8:27
  • Tried to make it more concise. Commented Sep 20, 2016 at 8:42
  • @Quentin, okay, I will try to write better. Commented Sep 20, 2016 at 8:53
  • @Quentin, I have rewritten my question. Commented Sep 20, 2016 at 9:03
  • 1
    Very nice, that improved it a lot ! I'm a bit lost in the different initializations, but the cppreference page for value initialisation states, before any description, that "In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of value-initialization.". Commented Sep 20, 2016 at 9:11

1 Answer 1

3

As a result of Core Issue 1301, which was a defect against C++11, the precedence for list-initialization changed from:

List-initialization of an object or reference of type T is defined as follows:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
  • Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1)

to:

List-initialization of an object or reference of type T is defined as follows:

  • If T is an aggregate, aggregate initialization is performed (8.5.1)
  • Otherwise, if the initialize list has no elements and T is a class type with a default constructor, the object is value-initialized.

So foo{} in Scenario A is still aggregate-initialization.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes, I understand BUT this change was in #3367 draft and it was accepted to C++14. But in Wiki I read that the draft #3337 is closest one to c++11. So in c++11 we DON'T have the change and so it looks like compilers when compiling as c++11 should not consider Scenario A as aggregate-initialization, am I right?
@JenyaKh Issue 1301 was a defect against C++11, so a conforming C++11 compiler should implement the change.
@JenyaKh defect reports are backwards-applied onto the corresponding standard. They're patch updates, if you will :)
This answer is outdated, but correct when it was written -- see p1008

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.