【问题标题】:Can I move construct (or assign) to a map a different type values using conversion?我可以使用转换将构造(或分配)移动到不同类型的地图吗?
【发布时间】:2022-01-02 22:57:39
【问题描述】:

我有一个简单的数据容器(为了解决这个问题而进行了更多简化),我将其用作地图中的值。

我想知道是否有某种方法可以将使用此容器作为值类型的地图从使用底层数据类型的地图中移动。

这是一个这样的类:

class D
{
public:
    D() :m_value(0.0){}
    D(double value) : m_value(std::move(value)) {}
    D(const D& from) : m_value(from.m_value) {}
    D(D&& from) : m_value(std::move(from.m_value)) {}
    D& operator= (const D& from) { m_value = from.m_value; return *this; }
    D& operator= (D&& from) { m_value = std::move(from.m_value); return *this; }
    ~D() = default;

    double m_value;
};

这是一个我想如何转换它的例子。

int main() {
    std::map<std::string, double> m = { { "1", 1.0 } };

    std::map<std::string, D> m_map = std::move(m);

    return 0;
}

这会产生以下错误:

error C2440: 'initializing' : cannot convert from 'std::map<std::string,double,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,D,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'

我想指出,我想移动构建这样一个地图的主要原因是避免创建地图键值的副本。在这种情况下是一个字符串。

【问题讨论】:

  • 我认为这行不通。地图的键是const,不能移动。
  • 你可以extract每个节点一个一个。分离的node_handle 中的键是可变的——key() 返回一个非常量引用——因此可以从中移动。然后您可以将emplace 碎片放入目标地图。
  • @IgorTandetnik 尽管有 const 键,但我希望它可行的原因是 std::map 的移动分配能够做到这一点。但是当值的类型不同时,我无法使用该移动分配。如果没有出现 c++11 解决方案,我会接受你的回答。我希望在这种情况下我可以使用更新版本的 c++。
  • Map 作为一个整体是可移动的,因为一个实例可以将指向其底层数据结构的指针传递给另一个实例;该数据结构保持不变。但是您想破坏该数据结构并清除它的部分。 extract 是我所知道的唯一方法。

标签: c++ c++11 type-conversion move-semantics


【解决方案1】:

可能是这样的(需要 C++17):

std::map<Key, long> new_m;
while (!m.empty()) {
    auto node = m.extract(m.begin());
    new_m.emplace(std::move(node.key()), std::move(node.mapped()));
}

Demo。我将用户定义的类设置为地图的键,而不是 std::string,以便我可以检测它并确认它确实被移动而不是复制。

【讨论】:

    猜你喜欢
    • 2022-06-10
    • 1970-01-01
    • 2018-02-16
    • 2022-11-05
    • 1970-01-01
    • 2019-07-01
    • 2017-11-07
    • 2022-08-17
    • 2018-08-11
    相关资源
    最近更新 更多