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

3
正如预期的那样,下面的代码无法编译
#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
}

但以下三个编译器中,变量 ok 的值都为真

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

为什么会这样呢?


4
你是如何确信它是真的?OK 的静态断言失败了。http://coliru.stacked-crooked.com/a/aba0debbfc609c11 - StoryTeller - Unslander Monica
1
std::cout << std::boolalpha << ok << '\n'; 在 Clang 5.0 中输出 false - Henri Menke
2
对于gcc < 6.3,“ok”为真。 - Holt
3
https://godbolt.org/g/cMfcBP,正如Holt所说,对于gcc <6.3是正确的,因此看起来像是一个bug。 - bolov
1
三个不同编译器中的一个bug,太棒了。 :D - Tobias Hermann
显示剩余4条评论
1个回答

5
  1. is_assignable asks the question "is there an assignment operator signature that accepts these arguments", not "will that assignment operator actually compile" (in standardese, it only considers the immediate context of the assignment expression):

    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
    }
    
  2. pair's assignment operators can't be defaulted, because it needs to do something special when the pair contains a reference. That means that additional precautions need to be taken to ensure that is_assignable doesn't lie (e.g., making sure that the copy assignment operator is deleted if a member type is not copy assignable). The standard has not mandated such precautions until very recently.

  3. is_assignable<T, T> asks whether a T rvalue can be assigned to a T rvalue. This is an odd question to ask.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接