In these features, T is not a reference type of lvalue, T implies rvalue.
With many custom T types, it is wise to assign rvalue types. And this is even very useful in some contexts:
std::vector<bool> v(5); v[0] = true;
In the above expression, v[0] is the value of r to which the value is assigned. And if vector<bool> is a bad example, then the following new C ++ 11 code does the same:
#include <tuple> std::tuple<int, int> do_something(); int main() { int i, j; std::tie(i, j) = do_something(); }
Above, the result of do_something() assigned to rvalue std::tuple . Assigning r values ββis useful and even common, although not done in the vast majority of assignment applications.
So, std::is_assignable allows you to distinguish between the ability to assign the value of r and lvalue. If you need to know the difference, std::is_assignable can do your job.
If you are dealing with a more common case, for example, just trying to figure out if type T is an assignable copy or not, use is_copy_assignable<T> . This trait is literally defined in terms of is_assignable and forces lhs to lvalue:
is_copy_assignable<T> == is_assignable<T&, const T&>
So std::is_copy_assignable<int>::value will be true as expected.
Use is_copy_assignable as your first choice, or is_move_assignable if you need it. Only when these traits do not work for you (perhaps because you need to look at the heterogeneous destination) should you return to using is_assignable directly. And then you need to solve the question of whether you want to allow rvalues ββto lhs in order to take into account cases that may include vector<bool>::reference or tuple links. You will need to explicitly indicate whether you want to resolve such cases in your is_assignable request.
For example:
#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"); }