C++ 增压变型在1_54中被摧毁?

C++ 增压变型在1_54中被摧毁?,c++,boost,c++11,variant,C++,Boost,C++11,Variant,我认为Boost::variant在1_54中被破坏了。 我试图在boost变量中使用std::unique_ptr作为有界类型 根据1_54文档,变体需要可复制构造或可移动构造 因此,我在代码中实现了move构造函数并禁用了copy构造函数 当我尝试将某些内容分配给variant对象时,它无法编译。 我尝试过各种不同的方法,包括使用std::move将数据分配给variant对象,但似乎没有任何效果。 在编译错误堆栈跟踪之后,我确定问题出在variant.hpp中,它试图备份rhs数据。我想

我认为Boost::variant在1_54中被破坏了。 我试图在boost变量中使用std::unique_ptr作为有界类型

根据1_54文档,变体需要可复制构造或可移动构造

因此,我在代码中实现了move构造函数并禁用了copy构造函数

当我尝试将某些内容分配给variant对象时,它无法编译。 我尝试过各种不同的方法,包括使用std::move将数据分配给variant对象,但似乎没有任何效果。 在编译错误堆栈跟踪之后,我确定问题出在variant.hpp中,它试图备份rhs数据。我想知道你们的想法,如果我认为boost变体文档是错误的,请告诉我

提前谢谢

我使用vs2010和C++11进行编译

以下是我的测试代码:

#include <iostream>
#include <memory>
#include <utility>
#include <vector>
#include <string>


#pragma warning (push)
#pragma warning (disable: 4127 4244 4265 4503 4512 4640 6011)
#include <boost/optional.hpp>
#include <boost/variant.hpp>
#include <boost/ref.hpp>
#include <boost/shared_ptr.hpp>
#pragma warning (pop)

#include <boost/foreach.hpp>
#include <boost/format.hpp>
using boost::format;
using boost::str;

using namespace std;

class UniqueTest
{
};

class Foo
{
  public:
  std::unique_ptr<UniqueTest> testUniquePtr;

     Foo()      { std::cout << "Foo::Foo\n";  }
     Foo (Foo&& moveData)
     {
     }               

     Foo& operator=(Foo&& moveData)
     {
     return *this;
     }

  private:
     Foo(Foo& tt);
     Foo& operator=(const Foo& tt);

};


int main()
{

  Foo x = Foo();
  boost::variant<std::wstring,Foo> m_result2;
     std::wstring  testString = L"asdf";

  m_result2 = testString; //Fails
  //m_result2 = std::move(testString); //Fails
  //m_result2 = std::move(x); //Fails

  boost::get<Foo>(m_result2).testUniquePtr.get ();
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#pragma警告(推送)
#杂注警告(禁用:4127 4244 4265 4503 4512 4640 6011)
#包括
#包括
#包括
#包括
#布拉格警告(pop)
#包括
#包括
使用boost::格式;
使用boost::str;
使用名称空间std;
类唯一性测试
{
};
福班
{
公众:
std::unique_ptr testUniquePtr;
Foo(){std::cout
我的代码是否为任何人编译

不,否则,variant将尝试调用缺少的复制构造函数。
(Foo::Foo(Foo const&)
甚至没有声明):

即使你真的申报了,它也不起作用:

test.cpp|43 col 6| error: ‘Foo::Foo(const Foo&)’ is private

评论中已提到,但您需要

  • 使复制构造函数成为复制构造函数(用于良好样式)

  • 要使移动构造函数/赋值
    noexcept
    ,否则(如
    std::vector
    variant
    将拒绝移动对象,因为它不会异常安全

    Foo(Foo && moveData) noexcept { }    
    Foo& operator=(Foo && moveData) noexcept { return *this; }
    
下面是一个在GCC和Clang上编译的简化示例:

#include <iostream>
#include <memory>
#include <string>
#include <boost/variant.hpp>

struct UniqueTest { };

struct Foo
{
public:
    std::unique_ptr<UniqueTest> testUniquePtr;

    Foo() { std::cout << "Foo::Foo\n"; }
    Foo(Foo && moveData) noexcept { }

    Foo& operator=(Foo && moveData) noexcept { return *this; }

    Foo(Foo const& tt) = delete;
    Foo& operator=(const Foo& tt) = delete;
};


int main()
{
    Foo x = Foo();

    boost::variant<std::wstring, Foo> m_result2;

    std::wstring  testString = L"asdf";
    m_result2 = testString; //Fails
    //m_result2 = std::move(testString); //Fails
    //m_result2 = std::move(x); //Fails
    boost::get<Foo>(m_result2).testUniquePtr.get();
}
#包括
#包括
#包括
#包括
结构唯一性{};
结构Foo
{
公众:
std::unique_ptr testUniquePtr;

Foo(){std::cout这不是“禁用复制构造函数”的意思:-s而您只“实现”最广义的移动构造函数。提示:删除所有手动移动和复制构造函数;隐式提供的构造函数就可以了。如果没有用户定义的复制操作或析构函数,则移动构造函数是自动生成的。删除所有断开的特殊成员函数,让编译器提供它们correctly@luke签名,那么这是一个MSVC错误,它使用符合标准的C++11进行编译compiler@DavidBrown,您需要进行用户定义的移动操作
noexcept
(因为默认的是隐式的).variant
将不使用move-ops,如果这样做可能导致抛出,以避免数据丢失,从而提供强异常安全性guarantee@lukesignh,我不知道它是否会对VS2010产生任何影响,但您可以尝试使您的移动构造函数
noexcept
,看看这是否会使
variant
优先使用它o您的私有(因此无法使用)复制构造函数。如果您不手动定义它,这应该是隐式的,但是VS2010早于C++11标准,我不知道支持多少。我刚刚看到您的帖子。VS2010不支持nodelite或noexcept关键字。除了自己定义它们之外,我还有其他选择吗?
Foo(Foo && moveData) noexcept { }    
Foo& operator=(Foo && moveData) noexcept { return *this; }
#include <iostream>
#include <memory>
#include <string>
#include <boost/variant.hpp>

struct UniqueTest { };

struct Foo
{
public:
    std::unique_ptr<UniqueTest> testUniquePtr;

    Foo() { std::cout << "Foo::Foo\n"; }
    Foo(Foo && moveData) noexcept { }

    Foo& operator=(Foo && moveData) noexcept { return *this; }

    Foo(Foo const& tt) = delete;
    Foo& operator=(const Foo& tt) = delete;
};


int main()
{
    Foo x = Foo();

    boost::variant<std::wstring, Foo> m_result2;

    std::wstring  testString = L"asdf";
    m_result2 = testString; //Fails
    //m_result2 = std::move(testString); //Fails
    //m_result2 = std::move(x); //Fails
    boost::get<Foo>(m_result2).testUniquePtr.get();
}