I am trying to pack a (STL-) container of type non-copyable in std :: optional, eg:
class MyClass
{
MyClass(const MyClass&) = delete;
};
std::optional<std::list<MyClass>> optContainer;
But the compiler (GCC 7.2) complains
error: using the remote function MyClass :: MyClass (const MyClass &) '{:: new ((void *) __p) _Up (std :: forward <_Args> (__ args) ...); }
[...] note: declared here
MyClass (const MyClass &) = delete;
and represents a deep "necessary from ..." stack going to type_traits (and more), where it checks std :: is_trivially_copy_constructible for std :: list. I suspect that the compiler detects that the container (std :: list in the example) is trivially copied constructively, but does not check the type of the container value for trivial constructability and then goes the wrong way.
Of course, the non-copyable type (not in the container) in std :: optional works:
std::optional<MyClass> optValue;
I know I can get around this. Mr. so:
template<typename T>
class CNonCopyable : public T
{
public:
template<typename... Params>
CNonCopyable(Params&&... params)
: T(std::forward<Params>(params)...)
{}
CNonCopyable(const CNonCopyable&) = delete;
CNonCopyable(CNonCopyable&&) = default;
virtual ~CNonCopyable() = default;
CNonCopyable& operator=(const CNonCopyable&) = default;
CNonCopyable& operator=(CNonCopyable&&) = default;
};
std::optional<CNonCopyable<std::list<MyClass>>> optContainer;
But I am wondering if there is a better way without the CNonCopyable class.
(Just like an example when the native type is not involved). The same thing happens when you try to pack the std :: unique_ptr container into std :: optional, because std :: unique_ptr is not constructive for copying:
std::optional<std::list<std::unique_ptr<int>>> optContainer;