gpt4 book ai didi

c++ - 子类化 std::optional 时编译错误

转载 作者:行者123 更新时间:2023-11-30 01:34:01 25 4
gpt4 key购买 nike

我正在尝试在 MS C++17 (VS2017) 中子类化 std::optional 以向该类添加消息字段,但出现编译错误

error C2280: 'OptMsg<bool>::OptMsg(const OptMsg<bool> &)': attempting to reference a deleted function

Intellisense 提供更多洞察力:

function "OptMsg<T>::OptMsg(const OptMsg<bool> &) throw() [with T=bool]" (declared implicitly) cannot be referenced -- it is a deleted function

这告诉我编译器对引用已删除函数的复制构造函数有问题抛出?我收到从函数返回实例的错误。例如,

OptMsg<bool> foo()
{
OptMsg<bool> res = false;
return res; // <-- Getting compile error here
}

这是我的类(class)。任何见解表示赞赏!

template <class T>
class KB_MAPPING_ENGINE_API OptMsg : public std::optional<T>
{
public:
constexpr OptMsg() noexcept
: optional{}
{}
constexpr OptMsg(std::nullopt_t) noexcept
: optional{}
{}
constexpr OptMsg(const T & other) noexcept
: optional<T>{other}
, m_Message{other.m_Message}
{}
constexpr explicit OptMsg(const T && other) noexcept
: optional<T>{other}
, m_Message{other.m_Message}
{}
OptMsg & operator = ( const OptMsg & other ) noexcept
{
if ( &other != this )
m_Message = other.m_Message;
return *this;
}
OptMsg && operator = ( const OptMsg && other )
{
if ( &other != this )
m_Message = other.m_Message;
return *this;
}

void SetMessage( const std::string & message ) { m_Message = message; }

std::string GetMessage() { return m_Message; }

private:
std::string m_Message;
};

最佳答案

Which tells me the compiler has in issue with my copy constructor referencing the deleted function throw?

不,没有函数throw()。这种表示法是 C++11 之前声明函数不抛出任何东西的方式。现在推荐 noexcept,但显然,Microsoft 还没有 catch ......

相反,错误告诉您您正在尝试调用复制构造函数(在您标记的行中),但您的类没有!

为什么没有呢?这里是

constexpr OptMsg(const T & other) noexcept
: optional<T>{other}
, m_Message{other.m_Message}
{}

看起来它打算成为复制构造函数。但是,这不是因为参数是 const T&。复制构造函数需要 const OptMsg&

通常,复制构造函数会自动为您声明。这并没有发生在这里,因为您显式声明了 operator=(const OptMsg&)。因此,错误消息提到您的复制构造函数是一个“已删除的函数”。

如何解决?

要么正确声明你的复制构造函数,要么移除赋值运算符。编译器将为您生成一个。但请注意,您当前的赋值运算符(复制和移动)实现仅分配消息而不分配 optional 本身。这是故意的吗?将是一个非常意外的行为......如果这是有意的,你必须自己声明一切(但正确!)。

但假设这不是预期的,并且进一步假设您的复制操作应该只是简单地复制整个实例(消息 + 基类),那么自动生成的构造函数和赋值运算符将完全按照您的意愿进行操作,无需编写它们你自己。但是,您可以将其写入您的类中,让每个人都能立即看到您正在使用编译器生成的类:

constexpr OptMsg() = default;

constexpr OptMsg(const OptMsg & other) = default;
constexpr OptMsg(OptMsg && other) = default;
OptMsg & operator = ( const OptMsg & other ) = default;
OptMsg & operator = ( OptMsg && other ) = default;

更新:

请注意,移动构造函数和移动赋值运算符需要 OptMsg&& 作为参数。你一直有 const OptMsg&&。因此你的错误信息

"operator =(const OptMsg &&)': is not a special member function which can be defaulted

另请查看 the rule of zero (感谢@Caleth)。

关于c++ - 子类化 std::optional 时编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57074624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com