std :: optional

时间:2018-02-26 15:38:00

标签: c++ c++17

我正在尝试将一个不可复制类型的(STL-)容器打包到std :: optional中,e。 g。:

class MyClass
{
    MyClass(const MyClass&) = delete;
};
std::optional<std::list<MyClass>> optContainer;

但编译器(GCC 7.2)抱怨

  

错误:使用已删除的函数'MyClass :: MyClass(const MyClass&amp;)'{:: new((void *)__ p)_Up(std :: forward&lt; _Args&gt;(__ args)...); }   
[...]注意:在这里宣布   
MyClass(const MyClass&amp;)=删除;

并提供一个深入的“required from ...”堆栈进入type_traits(以及更多),它在std :: list上检查std :: is_trivially_copy_constructible。我怀疑编译器发现容器(示例中的std :: list)可以简单地复制构造,但是不检查容器的值类型是否具有简单的可构造性,然后走错路径。

当然std :: optional中的不可复制类型(不在容器中)起作用:

std::optional<MyClass> optValue; // ok

我知道我可以解决这个问题。 G。像这样:

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;

但是我想知道没有CNonCopyable类是否有更好的方法。

(正如一个不涉及自己类型的例子:)当尝试将std :: unique_ptr的容器打包到std :: optional时会发生同样的情况,因为std :: unique_ptr不是可复制构造的:

std::optional<std::list<std::unique_ptr<int>>> optContainer;

1 个答案:

答案 0 :(得分:11)

这是GCC中的一个错误,此后已被修补。

请参阅8119080654

使用较新版本的GCC(例如8),您将不会遇到此问题。