This code compiles:
std::string f(bool a, std::string const& b)
{
if (a) return b;
return {};
}
This code also compiles:
std::string f(bool a, std::string const& b)
{
return a ? b : std::string{};
}
This code does not compile:
std::string f(bool a, std::string const& b)
{
return a ? b : {};
}
Given that both result values of the ?:
operator are required to be the same type, why doesn't it infer the type like it does in the first example?
It appears that this question might have a similar answer to this (which essentially boils down to "because nobody thought about it when writing the language specification"). However I still think it's useful to retain this question as the question itself is different, it's still sufficiently surprising, and the other wouldn't come up in searches for this issue.
List initialization is performed in the following situations: direct-list-initialization (both explicit and non-explicit constructors are considered) 1) initialization of a named variable with a braced-init-list (that is, a possibly empty brace-enclosed list of expressions or nested braced-init-lists)
Reason for initializing the const data member in initializer list is because no memory is allocated separately for const data member, it is folded in the symbol table due to which we need to initialize it in the initializer list.
But there are situations where initialization of data members inside constructor doesn’t work and Initializer List must be used. Following are such cases: const data members must be initialized using Initializer List.
Otherwise, if T is a specialization of std::initializer_list, the T object is direct-initialized or copy-initialized, depending on context, from a prvalue of the same type initialized from (until C++17) the braced-init-list . Otherwise, the constructors of T are considered, in two phases:
A braced initializer is not an expression and thus it has no type. See:
https://scottmeyers.blogspot.com/2014/03/if-braced-initializers-have-no-type-why.html
A braced initializer is a grammatical construct with special rules in the standard, explicitly specifying allowed use and type deduction. These special rules are needed exactly because braced initializers have no type. Using them in ?:
statements is not specified, and thus the program is ill-formed.
If you really need to hear the man himself say it three times in a row before you believe it, then:
https://youtu.be/wQxj20X-tIU?t=1792
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With