Reputation: 9996
Simple question about C++11 syntaxis. There is a sample code (reduced one from source)
struct Wanderer
{
explicit Wanderer(std::vector<std::function<void (float)>> & update_loop)
{
update_loop.emplace_back([this](float dt) { update(dt); });
}
void update(float dt);
};
int main()
{
std::vector<std::function<void (float)>> update_loop;
Wanderer wanderer{update_loop}; // why {} ???
}
I'd like to know, how it can be possible call constructor with curly brackets like Wanderer wanderer{update_loop};
It is neither initializer list, nor uniform initialization. What's the thing is this?
Upvotes: 24
Views: 11524
Reputation: 89
In addition, braces-constructors do not allow narrowing, similarly to braces-initialization.
Let's take a look at the simple constructor taking and printing an integer value:
class Test {
public:
Test(int i) {
std::cout << i << std::endl;
}
};
While Test test(3.14);
compiles and outputting narrowed 3
,
Test test{3.14};
would not even compile:
error: narrowing conversion of ‘3.1400000000000001e+0’ from ‘double’ to ‘int’ [-Wnarrowing]
11 | Test test{3.14};
| ^
Upvotes: 4
Reputation: 126552
It is neither initializer list, nor uniform initialization. What's the thing is this?
Your premise is wrong. It is uniform initialization and, in Standardese terms, direct-brace-initialization.
Unless a constructor accepting an std::initializer_list
is present, using braces for constructing objects is equivalent to using parentheses.
The advantage of using braces is that the syntax is immune to the Most Vexing Parse problem:
struct Y { };
struct X
{
X(Y) { }
};
// ...
X x1(Y()); // MVP: Declares a function called x1 which returns
// a value of type X and accepts a function that
// takes no argument and returns a value of type Y.
X x2{Y()}; // OK, constructs an object of type X called x2 and
// provides a default-constructed temporary object
// of type Y in input to X's constructor.
Upvotes: 32
Reputation: 227578
It is just C++11 syntax. You can initialize objects calling their constructor with curly braces. You just have to bear in mind that if the type has an initializer_list constructor, that one takes precedence.
Upvotes: 10