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

使用删除复制构造函数解决英特尔131.2中的C++行为不良

  •  1
  • gct  · 技术社区  · 6 年前

    我坚持支持回到英特尔131.2,这是名义上的C++ 11兼容,但这个代码:

    #include <algorithm>
    
    struct moveonly {
      moveonly()                =default;
      moveonly(const moveonly&) =delete;
      moveonly(moveonly&& other) { member = std::move(other.member); }
    
    private:
      int member = 0;
    };
    
    template <typename T>
    struct holds {
      operator T&&() { return std::move(t); }
      T t;
    };
    
    
    int main() {
      holds<moveonly> m;
      moveonly a = m;
    }
    

    未能编译:

     ╰─▸ icc -std=c++11 test.cc -o test
    test.cc(21): error: function "moveonly::moveonly(const moveonly &)" (declared at line 5) cannot be referenced -- it is a deleted function
        moveonly a = m;
                     ^
    
    test.cc(21): error: function "moveonly::moveonly(const moveonly &)" (declared at line 5) cannot be referenced -- it is a deleted function
        moveonly a = m;
                     ^
    
    compilation aborted for test.cc (code 2)
    

    假设我不能使类可复制,并且希望保留转换运算符,有人能想出解决方法吗?

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

    您可以尝试使rvalue显式:

    moveonly a = std::move(m);
    

    可能,显式cast也有帮助:

    moveonly a = static_cast<moveonly&&>(m);
    

    显式调用cast运算符:

    moveonly a = m.operator moveonly&&();
    

    如果全部失败,回到前C ++ 11意味着:

    struct holds
    {
        operator T&&() { return std::move(t); }
        T t;
        swap(T& tt)
        {
            swap(t, tt);
        }
    };
    

    为moveonly定义了适当的交换,因此您可以:

    moveonly a;
    m.swap(a);