首页 > c++ > 使用已删除的复制构造函数解决英特尔13.1.2中的C ++行为不佳问题

使用已删除的复制构造函数解决英特尔13.1.2中的C ++行为不佳问题 (Workaround for poor C++ behavior in Intel 13.1.2 with deleted copy constructor)

2018-08-08 c++c++11

问题

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

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

解决方法

您可以尝试使rvalue显式:

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

问题

I'm stuck supporting back to Intel 13.1.2, which is nominally C++11 compliant, but this code:

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

Fails to compile:

 ╰─▸ 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)

Assuming I can't make the class copyable, and would like to keep the conversion operator, can anyone come up with a workaround?

解决方法

You might try to make the rvalue explicit:

moveonly a = std::move(m);

Possibly, explicit cast helps as well:

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

Calling the cast operator explicitly:

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

If all fails, falling back to pre-C++11 means:

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

with appropriate swap defined for moveonly, so you could:

moveonly a;
m.swap(a);
相似信息