c++ - 您如何static_cast std::unordered_set?

标签 c++ casting stl unordered-set

我正在尝试static_cast一个unordered_set,我想知道如果没有未定义的行为,这是否有可能。

这是我要完成的工作:

#include <unordered_set>

struct  Base{};
struct Derived : public Base{ Derived() = default; };

int main(void){
    std::unordered_set<Base *> set;
    set.insert(new Derived{});
    auto set_ptr{static_cast<std::unordered_set<Derived *>*>(&set)};
}

我正在尝试将一组Base *静态转换为一组Derived *

但是,这不会出现错误:
main.cpp: In function ‘int main()’:
main.cpp:21:66: error: invalid static_cast from type ‘std::unordered_set*’ to type ‘std::unordered_set*’
     auto set_ptr{static_cast<std::unordered_set<Derived *>*>(&set)};

我想知道是否有一种方法可以不输入未定义的行为范围。

最佳答案

在大多数情况下,您无法针对模板参数执行强制转换,例如

MyTemplateClass<T> foo;
MyTemplateClass<U>& bar = std::static_cast<MyTemplateClass<U>&>(foo);

因为类型MyTemplateClass<U>MyTemplateClass<T>在继承结构方面是完全不相关的。两者之一甚至可以完全不同!

在您的情况下,MyTemplateClassstd::unordered_set

在使用诸如std::set<T*>之类的指针容器的情况下,我们对包含的内容有了更多的了解:指针,几乎没有什么可以做的:
  • 丑陋。非标准危险的。按照标准,这是未定义的行为。

    只需执行reinterpret_cast<std::unorederd_set<Derived*>&>即可。在大多数情况下都可以使用。但是,现在不破损是您的全部责任。例如,当使用Base*引用时,必须确保集合中没有std::unorederd_set<Derived*>元素。当您将其传递给函数或存储为某些对象的字段时,将很容易忘记。
  • 干净但是很干净。

    写一个适配器。您自己的std::unordered_set<Derived*>实现,在下面保留了对std::unordered_set<Base*>的引用,并在每次访问元素时执行所有必要的强制转换。

    例如,您很可能需要在其上编写自己的迭代器。访问者operator*将执行static_castdynamic_cast来访问其元素。或者更好的是,让迭代器仅在实际上是Derived*的元素上停止,并跳过所有其他Base*
  • 关于c++ - 您如何static_cast std::unordered_set?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60717400/

    相关文章:

    casting - 从原始指针到帽子指针的reinterpret_cast 的引用计数规则是什么?

    c++ - timeval 到字符串(在两者之间转换)

    c++11 - 在C++中,如何使用for_each反向迭代数组?

    c++ - STL 算法的反向迭代

    c++ - 如何欺骗 boost::asio 以允许仅 move 处理程序

    c++ - 这2张魔法卡能发挥的最大技能是多少?

    c# - 是否可以转换对象图?

    c++ - std::map key 与 operator< 不匹配

    c++ - std::is_trivially_xxx 其中一个暗示另一个

    android - Cmake 无法在 qt creator/collect2 : error: ld 上编译简单的测试程序