Following codes work as expected with results:
ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
same
same
same
#include <iostream>
#include <type_traits>
struct Test {
Test() {
std::cout << "Test ctor\n";
}
int func() {
return 1;
}
};
int main() {
if (std::is_same_v<decltype(std::add_rvalue_reference<Test>::type{}.func()),int>) {
std::cout <<"same\n";
} else {
std::cout <<"different\n";
}
if (std::is_same_v<decltype(Test().func()),int>) {
std::cout <<"same\n";
} else {
std::cout <<"different\n";
}
if (std::is_same_v<decltype(std::type_identity<Test>::type().func()),int>) {
std::cout <<"same\n";
} else {
std::cout <<"different\n";
}
}
However, if I replace std::add_rvalue_reference<Test>::type{}
with std::add_rvalue_reference<Test>::type()
, the following compilation errors are generated:
<source>:14:33: error: reference to type 'Test' requires an initializer
if (std::is_same_v<decltype(std::add_rvalue_reference<Test>::type().func()),int>) {
^
1 error generated.
ASM generation compiler returned: 1
<source>:14:33: error: reference to type 'Test' requires an initializer
if (std::is_same_v<decltype(std::add_rvalue_reference<Test>::type().func()),int>) {
^
1 error generated.
Execution build compiler returned: 1
Does anyone know what is causing std::add_rvalue_reference<Test>::type()
to fail to call the constructor of Test
, while Test()
and std::type_identity<Test>::type()
are fine?
@RemyLebeau is right. It is not allowed to value-initialize a reference, while list-initializing a reference from {}
works by creating a temporary.
A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.
List-initialization of an object or reference of type
T
is defined as follows:
- [...]
- Otherwise, if
T
is a reference type, a prvalue temporary of the type referenced byT
is list-initialized, and the reference is bound to that temporary.