我有以下测试程序:
#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));
}
我希望标有箭头的行会调用右值重载,就像它上面的非常量调用一样,但事实并非如此。
这只是 GCC 中的一个错误,还是标准中有什么东西导致选择左值重载?
最佳答案
根据标准§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).
所以 id<int const[]>{1, 2, 3, 4, 5}
是临时的,因此是纯右值 §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.
因此应选择具有右值引用参数的重载函数。
关于c++ - 临时 const 数组未绑定(bind)到右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17508703/