1
#include <iostream>
using namespace std;

struct Point
{
  int x;
  int y;
};

int main()
{
  //Point p(2, 3); // error: no matching constructor for initialization of 'Point'
  Point p{2, 3}; // fine
}

Question> Is it true that if we use uniform initialization to initialize a variable then we don't have to define the corresponding explicit constructor? As illustrated in above example, class Point has no constructor with two pass-in parameters, but the uniform initialization still works. I feel confused here and want to know the answer of my question.

Thank you

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
q0987
  • 34,938
  • 69
  • 242
  • 387
  • 1
    `explicit constructor` doesn't mean what you think it means. You mean, without a user-defined constructor. Your type is an aggregate and even C (and c++89, c++03) could initialize those with _brace-initialization_ – sehe Jul 29 '13 at 18:55
  • @sehe: I don't agree with this being a duplicate. The *answers* may be the same (or similar, since it's just about aggregates and not PODs), but the questions are very different. – Nicol Bolas Jul 29 '13 at 19:21
  • 1
    To me, "explicit constructor" means a user-written constructor. However an "`explicit` constructor" to me means a constructor declared with the "explicit" keyword or something equivalent (an implicitly declared inherited constructor with such an "`explicit`" meaning for example). – Johannes Schaub - litb Jul 29 '13 at 19:22
  • 1
    @sehe i disagree aswell. those questions are different, and the answers should probably be different too (and as far as I can see, they are). – Johannes Schaub - litb Jul 29 '13 at 19:23
  • Well. Of course the question is different. No _exact_ duplicate ever gets asked. In my mind, the OP was looking for the relevant information, and lacked the jargon. I pointed at it, and don't see why adding _this particular_ question over again adds value, just because it's not exactly the same question. – sehe Jul 29 '13 at 19:50
  • @sehe: His question is, in part, about uniform initialization. Which is *not covered* by the other question. Talking about aggregate initialization *without* saying that uniform initialization can invoke aggregate initialization is simply not answering his question. – Nicol Bolas Jul 29 '13 at 20:15
  • @NicolBolas Ok, perhaps that is true. I kind of assumed that a set of [tag:c++-faq] answers to _"What are Aggregates and PODs and how/why are they special?"_ with **combined votes of >+373** (122+134+117) would somehow *include their initialization*. If we can't trust our instincts in that matter, then I don't see how anyone in reality will ever have the "authority" to → *vote to* ← 'close as duplicate'. – sehe Jul 29 '13 at 20:48
  • @sehe: But *uniform* initialization has nothing to do with aggregates and PODs's *specifically*. The answers talk about the topic of the question: what aggregates and PODs are and how the language treats them specially. The only places where initialization matters for either types are discussed (trivially moveable and aggregate initialization), and neither one has to do with uniform initialization *specifically*. – Nicol Bolas Jul 29 '13 at 20:51
  • @NicolBolas gah. I don't think the linked question would fail to tell the OP everything he needed to know. Even if there is technically a _gap_. If it's any consolation, I'll +1 the question – sehe Jul 29 '13 at 21:04
  • doesn't matter whether that question includes how aggregates are initialized. this question is not about aggregates. that's a red herring. not only is the linked question not a dupe, but its information are redundant, because if you say "it is an aggregate, and this is how we can initialize aggregates...", he will add a constructor and say "see now i added a constructor and i can *still* use the brace initialization". We can trust our instrinct, and my instinct says that closing this as a dupe of that other question was all nonsense. – Johannes Schaub - litb Jul 30 '13 at 17:47

1 Answers1

3

The purpose of uniform initialization is to be a single means of initializing any object which can be initialized. It therefore can pick and choose the appropriate initialization mechanism to use internally for a particular type.

Point is an aggregate. In C++98/03, it therefore could be initialized with aggregate initialization, much like an array.

Point p = {3, 4};

That was legal in C++98/03.

In C++11, aggregate initialization is one of the possible ways for uniform initialization to initialize a variable. If the type being initialized is an aggregate, then the members of the braced-init-list are used to initialize it via aggregate initialization. But aggregate initialization in C++98/03 only worked in Typename var = braced-init-list; form. Uniform initialization allows all of these forms to use it as well:

Point p{3, 4};

void Func(const Point &p);
Func({3, 4});

Point Func2()
{
  return {3, 4};
}

All of these use uniform initialization to initialize a Point aggregate. However, since it's using uniform initialization syntax, you can later change Point to add a constructor. And as long as you add a constructor that takes two integers (and don't add an initializer_list constructor that takes integers), all your code will work just fine.

Community
  • 1
  • 1
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982