Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::is_assignable doesn't work with primitive types? (Confirmation)

To be more specific why std::is_assignable_v<int, int> << '\n'; returns false? Is it because an int has no overloaded assignment operator (being a primitive type and all)?

(by the way std::is_trivially_assignable_v<int, int> gives false too.)

Note that this: struct Structure {}; std::is_assignable<class Structure, class Structure>::value; would return true, because an overloaded assignment operator is implicitly defined for Structure.

Am i correct so far? If so then I suppose it wouldn't be trivial to enhance is_assignable to accept primitive types as well? Otherwise, any hints for such a possible work-around?

like image 650
KeyC0de Avatar asked Dec 11 '22 05:12

KeyC0de


2 Answers

An int cannot be assigned to an int. If you pass int& as a first argument instead, then, as expected, both is_assignable and is_trivially_assignable return true.

cppreference, godbolted

#include <type_traits>

int main()
{
    static_assert(!std::is_assignable_v<int, int>);
    static_assert(std::is_assignable_v<int&, int>);
    static_assert(!std::is_trivially_assignable_v<int, int>);
    static_assert(std::is_trivially_assignable_v<int&, int>);

    return 0;
}

A not so intuitive part — is_assignable_v<mytype, mytype> is true is because mytype{} = mytype{}; works too, and only is_assignable_v<mytype const, mytype> is false.

like image 80
bobah Avatar answered Mar 23 '23 01:03

bobah


If the expression std::declval<T>() = std::declval<U>() is well-formed in unevaluated context

std::is_assignable<int, int>::value << '\n' // 1 = 1; wouldn't compile

https://en.cppreference.com/w/cpp/types/is_assignable

like image 44
dan Avatar answered Mar 22 '23 23:03

dan