The type of a temporary is whatever type you declared it with.
Unfortunately, as Oliv points out in their answer reference initialization rules transform the type to match the reference type so in this case a
actually refers to a const A
. It is basically doing
using const_A = const A;
const A& a = const_A{};
Because you can actually create constant prvalues if you ever want to stop a overload set from accepting a constant prvalue you need to have
ret_type function_name(some_type const&&) = delete;
otherwise if you have
ret_type function_name(some_type const&)
in the overload set it then the constant prvalue would bind to that if you only deleted
ret_type function_name(some_type&&)
instead. You can see this working with
struct bar{};
void foo(bar const&) { std::cout << "void foo(bar const&)\n"; }
void foo(bar&&) =delete;
using c_bar = const bar;
int main()
{
foo(c_bar{});
}
Here, void foo(bar const&)
gets called since c_bar{}
is actually const
instead of getting a deleted function error if you had used foo(bar{});
. Adding
void foo(bar const&&) = delete;
is needed to actually stop foo(c_bar{});
from compiling.
A{}
is not const. You are simply creating a const reference to it, and then you are casting away that const-ness then accessing the temporary. That does not change the const-ness of the temporary itself. It is not UB to cast away const-ness from a pointer/reference if you are sure the object being pointed/referenced is not actually const. It WOULD be UB if the object were actually const, egconst A a; const A &ref = a; const_cast<A&>(ref).nonconst();
– ChromonemaA&&
. – Fibrinousstring() = "hello"
orvector<int>().push_back(1)
. (And there was no rvalue reference at that time.) – CounterintelligenceA{}
is not const. In C++17,A{}
does not even create a temporary object. – Vitascope