我可以使用转换将构造(或分配)移动到不同类型值的地图吗?

Can I move construct (or assign) to a map a different type values using conversion?

我有一个简单的数据容器(为了这个问题的目的进一步简化),我在地图中用作值。

我想知道是否可以通过某种方式从使用基础数据类型的地图中移动构建一个以该容器作为值类型的地图。

这里有这样一个class:

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>>>'

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

也许是这样的(需要 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。我将用户定义的 class 作为地图的键而不是 std::string,这样我就可以检测它并确认它确实被移动了而不是被复制了。