std :: unordered_map之间的reinterpret_cast

时间:2017-05-21 21:09:36

标签: c++ gcc unordered-map reinterpret-cast

我有以下unordered_map s:

 struct a{
        std::string b;
    };

    int main()
    {
        std::unordered_map<std::string, std::string> source;
        source["1"] = "Test";
        source["2"] = "Test2";

        std::unordered_map<std::string, a> dest = *reinterpret_cast<std::unordered_map<std::string, a>*>(&source);

        std::cout << dest["1"].b << std::endl;
        std::cout << dest["2"].b << std::endl;

    }

使用reinterpret_cast我将source转换为dest。这是有效的,因为struct a只包含std::string

我的问题:这实际上是很好的实践吗? GCC产生以下警告:

  

取消引用类型惩罚指针将破坏严格别名规则

我可以放心地忽略这个吗?或者只是转换STL容器的原始字节有任何潜在的缺点吗?

cpp.sh/5r2rh

1 个答案:

答案 0 :(得分:3)

不,这是良好做法。你的代码不安全。事实上,它恰恰相反:未定义的行为,意味着有时即使没有告诉你,它也会有效地发挥作用。

真正的问题是你没有&#34;合法&#34;将std::string转换为struct a的方法。这不是C,不要使用东西作为普通字节,使用该语言的类型系统。然后编译器将帮助您避免错误。

这是我的解决方案:

#include <unordered_map>
#include <string>
#include <iostream>
#include <algorithm>

struct a {
    std::string b;
    a () = default;
    a (const std::string& b) : b(b){}
};

int main() {
    std::unordered_map<std::string, std::string> source;
    source["1"] = "Test";
    source["2"] = "Test2";

    std::unordered_map<std::string, a> dest;

    std::transform(source.cbegin(),source.cend(),std::inserter(dest,dest.end()),[](const auto& value)
    {
        return std::forward_as_tuple(value.first,value.second);
    });

    std::cout << dest["1"].b << std::endl;
    std::cout << dest["2"].b << std::endl;
}

如果你有性能问题,你也可以添加一个移动构造函数等,但相信我,可读的干净代码,是快速代码。否则,bootle颈部不是非强制转换代码,而是使用地图,复制而不是移动等东西。但不要过早优化。