c++ - std::unordered_map 之间的reinterpret_cast

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

我有以下unordered_map:

 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 产生以下警告:

dereferencing type-punned pointer will break strict-aliasing rules

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

( cpp.sh/5r2rh )

最佳答案

不,这不是好的做法。您的代码不安全。事实上,情况恰恰相反:未定义的行为,这意味着有时有效有时无效,即使没有告诉您。

真正的问题是你没有“合法”的方式将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;
}

如果您有性能问题,您还可以添加移动构造函数等,但相信我,可读的干净代码就是快速代码。否则,问题不是非类型转换代码,而是使用 map 、复制而不是移动等东西。但不要过早优化。

关于c++ - std::unordered_map 之间的reinterpret_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44101820/

相关文章:

linux - 是否可以在没有 root 的情况下在 CentOS 上安装 g++?

c++ - 解释 Unresolved external C++

c++ - 如何检测何时按下特定键

php - 尝试用 PHP 编译 C 代码

c++ - X代码 6 : Unable to create watchpoint

c - 访问 C 文件中的汇编宏函数/指令

c++ - 自定义类的 unordered_map 在插入相同的键时不会导致错误

c++ - std::unordered_map 的自定义分配器设置增量值

c++ - 需要帮助理解与 friend 声明有关的段落

c++ - 使用 clang 编译 C++ 文件时出错