在这些特征中,并且T
不是左值引用类型,T
意味着右值。
对于许多用户定义的类型T
,分配给右值类型是完全合理的。它在某些情况下甚至非常有用:
std::vector<bool> v(5);
v[0] = true;
在上面的表达式中,v[0]
是一个被分配到的右值。如果vector<bool>
是一个糟糕的例子,那么下面的新 C++11 代码也会做同样的事情:
#include <tuple>
std::tuple<int, int>
do_something();
int
main()
{
int i, j;
std::tie(i, j) = do_something();
}
上面, 的结果do_something()
被分配给一个 rvalue std::tuple
。赋值给右值很有用,甚至很常见,尽管在大多数赋值用法中都没有这样做。
因此std::is_assignable
允许确定能够分配给右值和左值之间的区别。如果您需要知道区别,std::is_assignable
可以为您完成工作。
如果您正在处理更常见的情况,例如只是想弄清楚一个类型T
是否可以复制分配,那么使用is_copy_assignable<T>
. 这个特性是根据字面定义的,is_assignable
并强制 lhs 为左值:
is_copy_assignable<T> == is_assignable<T&, const T&>
正如预期的那样,这std::is_copy_assignable<int>::value
将是真的。
is_copy_assignable
用作您的首选,或者如果is_move_assignable
您也需要。只有当这些特征对您不起作用时(可能是因为您需要查看异构分配),您才应该恢复is_assignable
直接使用。然后您需要处理是否要在 lhs 上允许右值的问题,以便考虑可能涉及 avector<bool>::reference
或 atuple
引用的情况。您必须明确选择是否要在 is_assignable 查询中允许此类情况。
例如:
#include <type_traits>
#include <vector>
int
main()
{
static_assert(std::is_assignable<std::vector<bool>::reference&, bool>(),
"Should be able to assign a bool to an lvalue vector<bool>::reference");
static_assert(std::is_assignable<std::vector<bool>::reference, bool>(),
"Should be able to assign a bool to an rvalue vector<bool>::reference");
static_assert(std::is_assignable<bool&, std::vector<bool>::reference>(),
"Should be able to assign a vector<bool>::reference to an lvalue bool");
static_assert(!std::is_assignable<bool, std::vector<bool>::reference>(),
"Should not be able to assign a vector<bool>::reference to an rvalue bool");
}