删除复制构造函数的 Intel 13.1.2 中不良C++行为的解决方法

Workaround for poor C++ behavior in Intel 13.1.2 with deleted copy constructor

本文关键字:C++ 不良 解决 方法 构造函数 复制 Intel 删除      更新时间:2023-10-16

我坚持支持英特尔 13.1.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)

假设我无法使类可复制,并且想保留转换运算符,任何人都可以想出解决方法吗?

您可以尝试使右值显式:

moveonly a = std::move(m);

显式强制转换也可能有所帮助:

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

显式调用强制转换运算符:

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);