std :: is_assignable和std :: pair <const T,U>

Tob*_*ann 3 c++ c++11

正如所料,以下代码无法编译.

#include <type_traits>
#include <utility>
int main()
{
    using T = std::pair<const int, int>;
    const auto ok = std::is_assignable<T, T>::value; // true
    T x;
    T y;
    x = y; // compiler error
}
Run Code Online (Sandbox Code Playgroud)

但是以下三个编译器的值ok 是正确的.

  • g ++(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609
  • clang版本3.8.0-2ubuntu4(标签/ RELEASE_380/final)
  • MSVC++ 2017 15.2 26430.6

为什么是这样?

T.C*_*.C. 5

  1. is_assignable问一个问题"是否存在接受这些参数的赋值运算符签名",而不是"将赋值运算符实际编译"(在标准中,它只考虑赋值表达式的直接上下文):

    template<class T>
    struct foo {
        T t {};
        foo& operator=(const foo& r) { t = r.t; };
    };
    static_assert(std::is_copy_assignable<foo<const int>>::value, ""); // OK
    
    void bar() {
        foo<const int> f1, f2;
        f1 = f2; // explodes
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. pair的赋值运算符不能默认,因为当对包含引用时,它需要做一些特殊的操作.这意味着需要采取额外的预防措施以确保is_assignable不存在(例如,如果成员类型不可复制,则确保删除复制赋值运算符).该标准直到最近才强制要求采取这些预防措施.

  3. is_assignable<T, T>询问是否T可以将右值分配给T 右值.这是一个奇怪的问题.