能否通过类型转换将不同值类型的map移动构造或赋值到目标map?
报错原因
std::map的移动构造仅支持完全同类型的std::map实例之间操作,你代码中的std::map<std::string, double>和std::map<std::string, D>的value类型不同,属于完全不兼容的类型,因此无法直接转换,出现编译报错。
要实现避免std::string键拷贝的需求,可以通过以下方案实现,性能和直接移动map几乎一致:
方案1:C++17及以上(最优性能)
使用C++17新增的extract接口直接提取原map的节点,转移键的所有权,完全避免键的拷贝:
int main() { std::map<std::string, double> m = { { "1", 1.0 } }; std::map<std::string, D> m_map; while (!m.empty()) { // 提取原map的首节点,不触发键的拷贝 auto node = m.extract(m.begin()); // 移动键的所有权转移到新map,value构造为D类型 m_map.insert( std::make_pair( std::move(node.key()), D(std::move(node.mapped())) ) ); } return 0; }
该方案没有任何字符串拷贝开销,节点的键直接在原节点和新map之间转移所有权,符合你的性能需求。
方案2:兼容C++11/14
如果使用更低版本的C++标准,可以通过移动构造键的方式实现,确保操作完成后不要再使用原map即可:
int main() { std::map<std::string, double> m = { { "1", 1.0 } }; std::map<std::string, D> m_map; for (auto&& elem : m) { m_map.emplace( std::piecewise_construct, // 移动原键所有权,const_cast安全因为原map后续不再使用 std::forward_as_tuple(std::move(const_cast<std::string&>(elem.first))), std::forward_as_tuple(std::move(elem.second)) ); } return 0; }
内容的提问来源于stack exchange,提问作者user3328152
相关产品推荐
相关产品推荐

