Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't C++ allow implicit list initialization in the conditional operator? [duplicate]

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.

like image 428
Miral Avatar asked May 15 '19 00:05

Miral


People also ask

What is list initialization in C++?

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)

Why do we initialize the const data member in initializer list?

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.

When to use initializer list instead of constructor in Java?

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.

How is a T object initialized in C++?

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:


1 Answers

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

like image 113
Nikos C. Avatar answered Oct 08 '22 13:10

Nikos C.