问题
I have the following test program:
#include <iostream>
#include <type_traits>
#include <utility>
template<typename Ty, std::size_t N>
void foo(Ty (&&)[N])
{
std::cout << "Ty (&&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}
template<typename Ty, std::size_t N>
void foo(Ty (&)[N])
{
std::cout << "Ty (&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}
template<typename Ty>
using id = Ty;
int main()
{
std::cout.setf(std::cout.boolalpha);
foo(id<int[]>{1, 2, 3, 4, 5});
foo(id<int const[]>{1, 2, 3, 4, 5}); // <-- HERE.
int xs[]{1, 2, 3, 4, 5};
foo(xs);
int const ys[]{1, 2, 3, 4, 5};
foo(ys);
foo(std::move(xs));
foo(std::move(ys));
}
I would expect that the line marked with an arrow would call the rvalue overload like the non-const call just above it but it doesn't.
Is this just a bug in GCC or is there something in the standard that causes the lvalue overload to be selected?
回答1:
According to the standard §12.2 [class.temporary]
:
Temporaries of class type are created in various contexts: binding a reference to a prvalue (8.5.3), returning a prvalue (6.6.3), a conversion that creates a prvalue (4.1, 5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering a handler (15.3), and in some initializations (8.5).
So id<int const[]>{1, 2, 3, 4, 5}
is a temporary and therefore is an prvalue §3.10 [basic.lval]
:
An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object.
A prvalue (“pure” rvalue) is an rvalue that is not an xvalue.
Hence shall be selected overloaded function with rvalue reference argument.
来源:https://stackoverflow.com/questions/17508703/temporary-const-array-not-binding-to-rvalue-reference