代码之家  ›  专栏  ›  技术社区  ›  KeyC0de

为什么实现is\u copy\u assignable不起作用?

  •  0
  • KeyC0de  · 技术社区  · 6 年前

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

    它们都是假的。

    (当时我意识到declval与方便的void_t结合使用——当然还有decltype——可以用来做类似的事情。)但我仍然不明白为什么这个不起作用。我想我们要测试一下 const T& 可分配给 T& (与复制赋值运算符一样)。那为什么呢?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Jarod42    6 年前

    你的 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
    {};