I noticed that the constructor with parentheses behaves differently, at least for floats and ints.
// int a, b{}, c = T(), d = T{}, e();
float a, b{}, c = T(), d = T{}, e();
endl(std::cout << a << ", " << b << ", " << c << ", " << d << ", " << e);
// 0, 0, 0, 0, 1
It's not a default constructor, the parentheses were parsed as part of the type. I printed the types, and e
has type float (&)()
(or just float()
with proper forwarding), so I think it's a default-constructed function. The result of calling it has a type, but calling it results in the linker error you'd expect. Its value would be 0 if it were a function pointer. Why would its value be 1, or how does it end up as 1 when it's printed?
It's not a function pointer, it's literally a function (albeit an undefined one).
By streaming the expression e
, which decays, you're creating a pointer to that function, and said pointer is valid because it points to the function you've declared called e
. Hence, 1
.
You're right to say that if you declared a function pointer to begin with, and made it nullptr
, you'd see 0
instead by streaming it. But functions and function pointers are two different things.