Почему реализация is_copy_assignable не работает? - PullRequest
0 голосов
/ 21 сентября 2018

Это моя попытка реализации 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
{};

Это был сбой.

Вот контрольные примеры:

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';
}

Все они печатают false.

(Тогда я понял, что declval в сочетании с удобным void_t - и конечно же decltype - можетвместо этого.) Но я до сих пор не понимаю, почему этот не работает.Я думаю, что мы хотим проверить, можно ли const T& назначить T& (как это делает оператор копирования).Ну почему тогда?

1 Ответ

0 голосов
/ 21 сентября 2018

Ваш decltype(std::add_lvalue_reference<T>::type = std::add_lvalue_reference<const T>::type, void()) плохо сформирован для каждого T, поскольку std::add_lvalue_reference<T>::type на самом деле не значение, а тип.

std::declval может помочь:

Вы хотитевместо этого отметьте выражение std::declval<T&>() = std::declval<const T&>().

Итак

template<typename T>
struct IsCopyAssignable<T,
                       decltype(std::declval<T&>() = std::declval<const T&>(), void())>
       : std::true_type
{};
...