Reputation: 5267
This is my attempt at an implementation for is_copy_assignable:
template<typename, typename = void>
struct IsCopyAssignable : std::false_type
{};
template<typename T>
struct IsCopyAssignable<T, decltype(std::add_lvalue_reference<T>::type = std::add_lvalue_reference<const T>::type, void())> : std::true_type
{};
It was a failure.
Here's the test cases:
int main()
{
struct Structure {};
std::cout << "IsCopyAssignable=\n";
std::cout << IsCopyAssignable<int>::value << '\n'; // should be true
std::cout << IsCopyAssignable<int&>::value << '\n'; // should be true
std::cout << IsCopyAssignable<const int&>::value << '\n'; // should be false
std::cout << IsCopyAssignable<const double&>::value << '\n'; // should be false
std::cout << IsCopyAssignable<class Structure>::value << '\n'; // should be true
std::cout << '\n';
}
They all print false.
(I realized then that declval in combination with the handy void_t - and decltype of course - can be used for things like these instead.) But I still do not understand exactly why this one doesn't work. I think we want to test whether const T&
can be assigned to T&
(as the copy assignment operator does). Well, why then?
Upvotes: 0
Views: 171
Reputation: 217283
Your decltype(std::add_lvalue_reference<T>::type = std::add_lvalue_reference<const T>::type, void())
is ill formed for every T
as std::add_lvalue_reference<T>::type
is actually not a value, but a type.
std::declval
might help:
You want to check instead expression std::declval<T&>() = std::declval<const T&>()
is valid.
So
template<typename T>
struct IsCopyAssignable<T,
decltype(std::declval<T&>() = std::declval<const T&>(), void())>
: std::true_type
{};
Upvotes: 1