我正在尝试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>
在继承结构方面是完全不相关的。两者之一甚至可以完全不同!在您的情况下,
MyTemplateClass
是std::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_cast
或dynamic_cast
来访问其元素。或者更好的是,让迭代器仅在实际上是Derived*
的元素上停止,并跳过所有其他Base*
。 关于c++ - 您如何static_cast std::unordered_set?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60717400/