如何在 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的成员并手动将他们移动到地图中。