在两个具有公共基础的模板类之间安全地转换

问题描述 投票:0回答:1

考虑以下因素

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。我已经搜索了答案,但与此相关的大多数问题都是“以这种特定方式进行安全吗”的形式。我的问题是有什么安全的方法可以做到这一点。

我发现的一些方法是:

  • 直接投射:
    ( Variant2< int > & ) value
    或使用相同的
    reinterpret_cast
  • 投射到
    Wrapper<int> &
    ,然后投射到
    Variant2<int> &

编辑

具体例子:

Variant1< int > val{ .t = 5 };
Variant2< int > & ref = ?Convert?( val );

目标:

目标是能够创建“标记”类型,它只是充当包装类型的代理,并防止两个不同标签的意外混合。然而,有时需要显式地从一个标签转换为另一个标签。这应该是编译时的事情,因此不会真正造成任何开销。

c++ templates casting
1个回答
0
投票

有没有办法将例如

Variant1<int> &
转换为
Variant2<int> &
而不触发UB

不。如果您只是将一个派生类重新解释为另一个派生类,它也会破坏多态性的全部意义。 那么

Wrapper
有什么意义,为什么不能直接使用
std::any

目标是能够创建“标记”类型,它只是充当包装类型的代理,并防止两个不同标签的意外混合。

这听起来像

Wrapper
应该包含
T
并且还有一个单独的标签类型作为成员。 或者,如果每个
std::variant<Variant1<int>, Variant2<int>>
都可以由
VariantX
构造,那么
Wrapper
可能是有意义的。 在这种情况下,您可以使用
std::visit
来获取您想要的任何“标记类型”。

无论如何,您都没有提供足够的详细信息来实现完整的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.