The forced version is disconnected in 1_54?

I think Boost :: variant is unpacked at 1_54. I am trying to use std :: unique_ptr as a limited type in the boost variant.

According to the documentation 1_54, the variant must be copyable or Move Constructable.

http://www.boost.org/doc/libs/1_54_0/doc/html/variant/reference.html

So, I applied move constructors and disabled copy constructors in my code.

When I try to assign something to a variant, it does not compile. I tried various things, including using std :: move to assign data to a variant of an object, but nothing works. After tracing the stack of compilation errors, I decided the problem was with the .hpp option, where it was trying to back up the rhs data. I would like to know what you guys are thinking and let me know if I am right that the extended documentation is wrong.

Thanks in advance.

I am compiling with vs2010 and using C ++ 11.

Here is my test code:

#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; } 
+6
source share
1 answer

How is my code compiling for anyone?

No, no, the option will try to call the copy constructor, which is missing. (Foo::Foo(Foo const&) is not even declared):

 boost/variant/variant.hpp|756 col 9| error: no matching function for call to 'Foo::Foo(const Foo&)' 

Even if you declared it, this will not work:

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

This was mentioned in the comments, but you need to

  • to make a copy constructor a copy constructor (for a good style)

     Foo(Foo const& tt) = delete; Foo& operator=(const Foo& tt) = delete; 
  • to make the constructor / destination of the move noexcept , otherwise (e.g. std::vector ) variant will refuse to move things because it will not be safe for everyone.

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

Here's a simplified example that compiles to GCC and 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(); } 
+4
source

Source: https://habr.com/ru/post/957157/


All Articles