C++ 在基本类型上使用std::declval

C++ 在基本类型上使用std::declval,c++,c++11,C++,C++11,当模板参数T是基本类型,例如int(在gcc 4.8中)时,以下代码无法编译。这是符合标准的行为吗?我对std::declval的理解是,它总是解析为T&或T& template <class T> void foo(T&& val) { std::cout << noexcept(std::declval<typename std::decay<T>::type>() = val); } struct bar { }; ba

当模板参数
T
是基本类型,例如
int
(在gcc 4.8中)时,以下代码无法编译。这是符合标准的行为吗?我对
std::declval
的理解是,它总是解析为
T&
T&

template <class T>
void foo(T&& val)
{
  std::cout << noexcept(std::declval<typename std::decay<T>::type>() = val);
}

struct bar { };
bar b;
foo(b); // okay

int a;
foo(a); // error: using xvalue (rvalue reference) as lvalue
模板
无效foo(T&&val)
{

std::cout您正试图分配给一个右值。
std::declval()
正确地返回一个类型
int&
。它没有名称,因此它是
int
类型的右值(更准确地说,是xvalue)。然后您正试图将
val
分配给这个右值,这对于基本类型是非法的


下面是一个以简化形式演示问题的示例(没有
declval
).

您似乎试图复制
std::is_nothrow\u copy\u assignable
?几乎。如果
T
是一个左值引用,我想检查nothrow copy assign,但是如果
T
是一个右值引用,我想检查nothrow move assign。+1在foo中,val的类型是int&没有衰减,declval给出您也可以使用int&。使用decay时,您会得到int&->int->int&&.ah,当然。我应该使用
std::declval()
。谢谢!@marack或只是
std::declval()
:P@Simple是的,说得好。我忘了
T&&&
折叠为
T&
。谢谢。@marack更不用说你例子中的
T
对于任何
U
都不会是
U&
类型;它要么是非参考
U
,要么是
U&