考虑以下
template<typename T>
struct Wrapper{ T t; };
template<typename T>
struct Variant1 : public Wrapper< T >
{
// ... Member types, static members, non virtual functions ... //
}
template<typename T>
struct Variant2 : public Wrapper< T >
{
// ... Member types, static members, non virtual functions ... //
}
字符串
有没有一种方法可以将例如Variant1<int> &
转换为Variant2<int> &
而不触发UB。我已经搜索了SO的答案,但与此相关的大多数问题都是“这样做安全吗”的形式。我的问题是有没有安全的方法来做到这一点。
我发现的一些方法是:
- 直接铸造:
( Variant2< int > & ) value
或相同使用reinterpret_cast
- 转换为
Wrapper<int> &
,然后转换为Variant2<int> &
编辑
具体示例:
Variant1< int > val{ .t = 5 };
Variant2< int > & ref = ?Convert?( val );
型
目标:
目标是能够创建“Tagged”类型,它只是作为 Package 类型的代理,并防止两个不同标记的意外混合。然而,有时需要显式地从一个标记转换到另一个标记。这应该是编译时的事情,因此不会真正引起任何开销。
1条答案
按热度按时间zazmityj1#
有没有办法将
Variant1<int> &
转换为Variant2<int> &
而不触发UB不。如果你只是把一个派生类重新解释为另一个派生类,那么多态性的意义也就不复存在了。那么
Wrapper
的意义是什么呢?为什么你不能直接使用std::any
呢?我们的目标是能够创建“标记”类型,它只是作为 Package 类型的代理,并防止两个不同标记的意外混合。
这听起来像是
Wrapper
应该包含T
和一个单独的标记类型作为成员。或者,如果每个VariantX
都可以从Wrapper
构造,那么std::variant<Variant1<int>, Variant2<int>>
可能是有意义的。在这种情况下,您可以使用std::visit
来获得您想要的任何“标记类型”。在任何情况下,您都没有提供完整解决方案所需的足够详细信息。