如何安全地复制具有 `std::variant` 成员的类?

Ευά*_*τος 6 c++ c++17 std-variant

以下示例在Container container2(container1);删除该行的情况下构建并正常运行。似乎std::variant删除了自身的复制构造函数,这使得 myContainer的复制构造函数被隐式删除。

实际上,我在问:

  1. 将 a 存储std::variant为成员的正确方法是什么?
  2. Container允许安全复制/移动分配之前必须实现什么?
#include <string>
#include <variant>

class A {};

class Container {
 public:
  Container(int i) : data_(i) {}
  Container(float f) : data_(f) {}
  Container(std::string s) : data_(s) {}
  Container(std::unique_ptr<A> a) : data_(std::move(a)) {}
  std::variant<int, float, std::string, std::unique_ptr<A>> data_;
};

int main() {
  Container container1{3};
  
  // error: call to implicitly-deleted copy constructor of 'Container'
  // 
  // copy constructor of 'Container' is implicitly deleted because
  // field 'data_' has a deleted copy constructor
  Container container2(container1);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*ers 10

cppreference有关于std::variant的复制构造函数的说法:

复制构造函数。[...] 此构造函数被定义为已删除,除非std::is_copy_constructible_v<T_i>对所有T_iin都为真Types。[...]

换句话说,它不会被删除,除非它std::variant可以包含的一种或多种类型由于某种原因不可复制。在你的情况下,这std::unique_ptr是导致问题的原因。或许std::shared_ptr会更合适。