如何在 C++ 中从 initializer_list 和 non-copyable 成员创建映射?
How to create a map from initializer_list with non-copyable members in C++?
所以,我有一个存储 objects 的 class 的映射,其中删除了复制构造函数,因为它有一个 unique_ptr 作为成员之一。我正在尝试使用 std::initializer_list 构建此映射,但我遇到了一个巨大的错误,以“使用已删除的函数 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&)”。如果我理解正确的话,其原因是列表的成员不是临时的,而是常量引用,因此你不能移动它们,无论是隐式的还是显式的。
这是header的部分:
class ExitMessage {
public:
...
ExitMessage( const std::string& text,
std::initializer_list<std::map<std::string, ExitMessage>::value_type> subMessages);
...
private:
std::string _text;
std::unique_ptr<std::map<std::string, ExitMessage>> _subMessages;
...
};
这是有问题的构造函数:
ExitMessage::ExitMessage( const std::string& text,
std::initializer_list<std::map<std::string, ExitMessage>::value_type> subMessages )
: _text( text ), _subMessages( new std::map<std::string, ExitMessage>( subMessages ) ) { }
那么,我该怎么做才能使用 std::initializer_list 创建此 class 的实例?
所以,我在构造函数上做了一些工作,并设法自己提出了解决方案。由于我的对象不可复制,因此将 initializer_list 对的第二个参数设为右值没有任何缺点。
std::initializer_list<std::pair<const std::string, ExitMessage&&>>
但是,现在我不能为地图使用默认构造函数,所以我不得不自己编写一个初始化循环。
ExitMessage::ExitMessage( const std::string& text,
std::initializer_list<std::pair<const std::string, ExitMessage&&>>&& subMessages )
: _text( text ) {
_subMessages = std::make_unique<std::map<std::string, ExitMessage>>();
for (const std::pair<const std::string, ExitMessage&&>& subMessage : subMessages) {
auto& subMessageRef = const_cast<std::pair<const std::string, ExitMessage&&>&>(subMessage);
_subMessages->emplace( subMessageRef.first, std::move( subMessageRef.second ) );
}
}
因为我现在确定参数对象是临时的或显式移动的(由于删除了复制构造函数,这在以前仍然是一个要求,只是不是列表本身),我可以安全地取消常量 initializer_list的成员并手动将他们移动到地图中。
所以,我有一个存储 objects 的 class 的映射,其中删除了复制构造函数,因为它有一个 unique_ptr 作为成员之一。我正在尝试使用 std::initializer_list 构建此映射,但我遇到了一个巨大的错误,以“使用已删除的函数 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&)”。如果我理解正确的话,其原因是列表的成员不是临时的,而是常量引用,因此你不能移动它们,无论是隐式的还是显式的。
这是header的部分:
class ExitMessage {
public:
...
ExitMessage( const std::string& text,
std::initializer_list<std::map<std::string, ExitMessage>::value_type> subMessages);
...
private:
std::string _text;
std::unique_ptr<std::map<std::string, ExitMessage>> _subMessages;
...
};
这是有问题的构造函数:
ExitMessage::ExitMessage( const std::string& text,
std::initializer_list<std::map<std::string, ExitMessage>::value_type> subMessages )
: _text( text ), _subMessages( new std::map<std::string, ExitMessage>( subMessages ) ) { }
那么,我该怎么做才能使用 std::initializer_list 创建此 class 的实例?
所以,我在构造函数上做了一些工作,并设法自己提出了解决方案。由于我的对象不可复制,因此将 initializer_list 对的第二个参数设为右值没有任何缺点。
std::initializer_list<std::pair<const std::string, ExitMessage&&>>
但是,现在我不能为地图使用默认构造函数,所以我不得不自己编写一个初始化循环。
ExitMessage::ExitMessage( const std::string& text,
std::initializer_list<std::pair<const std::string, ExitMessage&&>>&& subMessages )
: _text( text ) {
_subMessages = std::make_unique<std::map<std::string, ExitMessage>>();
for (const std::pair<const std::string, ExitMessage&&>& subMessage : subMessages) {
auto& subMessageRef = const_cast<std::pair<const std::string, ExitMessage&&>&>(subMessage);
_subMessages->emplace( subMessageRef.first, std::move( subMessageRef.second ) );
}
}
因为我现在确定参数对象是临时的或显式移动的(由于删除了复制构造函数,这在以前仍然是一个要求,只是不是列表本身),我可以安全地取消常量 initializer_list的成员并手动将他们移动到地图中。