【问题标题】:Move a pair into vector将一对移动到向量中
【发布时间】:2015-09-08 16:04:35
【问题描述】:

我有这个函数模板:

template<typename Collection, typename T>
void insertColElement(Collection col, const T& element, std::true_type)
{
    col.insert(col.end(), std::move(element));
}

如果 T 是可移动构造的,则调用它。现在我想用 Collection = std::vector&lt;..&gt; 和 T = std::pair&lt;std::unique_ptr&lt;..&gt;, bool&gt; 调用这个函数,但是编译器抱怨删除了 unique_ptr 和 pair 的复制构造函数。我已经尝试过使用 emplace 并分别移动 first 和 second ,但是编译器仍然想调用复制构造函数。

编辑:

这里是所有相关代码sn-ps:

template<typename Collection, typename T>
void insertColElement(Collection col, T&& element, std::true_type)
{
    col.insert(col.end(), std::forward<T>(element));
}



template<typename Collection, typename T>
void insertColElement(Collection col, T& element, std::false_type)
{
    static_assert(std::is_copy_constructible<T>::value,
        "Serialization: Collection type is neither copy nor move constructable");

    col.insert(col.end(), element);
}


template<typename Archive, typename Collection>
inline void loadCollection(Archive& ar, Collection& col)
{
    int size;
    ar >> size;

    for(int i = 0; i < size; i++) {
        typename Collection::value_type element;
        ar >> element;

        insertColElement(col, std::move(element), 
            typename std::is_move_constructible<typename Collection::value_type>::type());
    }
}

这些函数是我正在研究的一个小型序列化模块的一部分。 loadCollection 用于从档案中加载容器。导致问题的调用如下所示:

IStreamArchive a(filestream);
std::vector<std::pair<std::unique_ptr<Scope>, bool>> vec;
a << vec;

【问题讨论】:

    标签: c++ c++11 move std-pair


    【解决方案1】:

    你不能从 const 中移动,所以即使你写了move(),你最终还是会得到复制构造函数(因为move 只是一个转换,所以你将元素转换为const T&amp;&amp;。那里没有const T&amp;&amp; 构造函数,并且T&amp;&amp; 构造函数不匹配,因此下一个最佳匹配是const T&amp; 构造函数)。这就是问题所在。

    您应该改为编写以下内容:

    template<typename Collection, typename T>
    void insertColElement(Collection& col, T&& element, std::true_type)
    {
        col.insert(col.end(), std::forward<T>(element));
    }
    

    【讨论】:

    • 我仍然得到这些编译器错误。我这样调用函数:typename Collection::value_type element; insertColElement(col, std::move(element), typename std::is_move_constructible&lt;typename Collection::value_type&gt;::type()); 我对移动语义还不是很熟悉,所以我不知道 std::move 是否在正确的位置。
    • @JonasThiele 你能提供一个完整的例子吗?
    • @JonasThiele 您正在按值传递集合 - 您无法复制包含不可复制内容的容器。我意识到我在我的回答中也忘记了&amp;。请注意,这也是不必要的,因为您可以直接使用col.push_back(std::move(element));
    • 哇哦。我没注意到,谢谢你指出这个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    相关资源
    最近更新 更多