【问题标题】:R-value inserts don't work for unordered_mapR 值插入不适用于 unordered_map
【发布时间】:2011-06-16 03:25:35
【问题描述】:

我正在使用来自存储库的最新可用 GCC 构建。我决定使用它是因为一些额外的 C++0x 特性。但是现在我坚持了一些应该起作用的东西——我想通过 r 值添加新元素来映射。简化代码,演示问题:

#include <tr1/unordered_map>

class X
{
    public:
        X (void) { /* ... */ };
        X (const X& x) = delete;
        X (X&& x) { /* ... */ };
};

int main (void)
{
    std::tr1::unordered_map<int, X> map;

    // using std::tr1::unordered_map<int, X>::value_type didn't help too
    std::pair<int, X> value (1, X ());

    map.insert (std::move (value));
}

请注意,当将 X 类替换为诸如 int 之类的原始类型时,代码可以编译并正常工作。

在我的生产代码中,对应于 X 的类也没有复制构造函数。

错误消息(与所有模板相关的错误一样)很长且不可读,我不确定将其放在这里是否是个好主意。如果您需要错误消息,请通知我,因此我将更新此问题。消息的最后一部分很有趣:

(...)
/usr/include/c++/trunk/ext/new_allocator.h:106:9: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int, _T2 = X, std::pair<_T1, _T2> = std::pair<const int, X>]’
In file included from /usr/include/c++/trunk/utility:71:0,
                 from /usr/include/c++/trunk/tr1/unordered_map:34,
                 from kod.cpp:1:
/usr/include/c++/trunk/bits/stl_pair.h:110:17: error: ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int, _T2 = X, std::pair<_T1, _T2> = std::pair<const int, X>]’ is implicitly deleted because the default definition would be ill-formed:
/usr/include/c++/trunk/bits/stl_pair.h:110:17: error: use of deleted function ‘X::X(const X&)’

此外,这应该可以工作,因为类似的错误已经修复[C++0x] Implement emplace* in associative and unordered containers

也许我做错了什么?我想在报告之前确定这是 GCC 或 libstdc++ 错误。

【问题讨论】:

  • Missing R-Value compatible 'insert' 方法现在在未发布的 GCC 4.6.0 中可用。

标签: c++ c++11 tr1


【解决方案1】:

除了您使用 tr1 之外,您的代码在我看来是正确的。 tr1 限定的东西不知道右值引用或移动语义。

我获取了您的代码,从标头和命名空间限定符中删除了 tr1,并使用 g++-4.4 和 libc++ (http://libcxx.llvm.org/) 成功编译了您的代码。尝试删除 tr1。

【讨论】:

  • 有效,前段时间很奇怪,当我尝试使用某些 TR1 功能时,编译器强迫我使用“tr1”命名空间...
  • tr1 指非规范性技术报告。这意味着其中的任何功能都被认为是可选的——标准不需要它们。 tr1 包含许多随后被移至 C++0x 的库组件。有时在从 std::tr1 到 std:: 的移动过程中,组件被修改了。向 unordered_map 添加移动语义就是这种修改的一个示例。 tr1 早于 C++0x。您可能一直在使用具有 tr1 但没有 C++0x 功能的版本。
【解决方案2】:

unordered_map 中的value_type 不是std::pair&lt;int, X&gt;。它是std::pair&lt;const int, X&gt;。也许如果您将这种类型用于value,它会更好地工作。

decltype(map)::value_type value(1, X());
map.insert(std::move(value));

虽然我不完全明白为什么您的代码不应该按原样工作。

【讨论】:

    猜你喜欢
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多