C++ 根据布尔值在两个typedef结构之间切换

C++ 根据布尔值在两个typedef结构之间切换,c++,struct,typedef,C++,Struct,Typedef,我有一个具有不同功能的类。此类使用两个typedef结构 typedef struct { struct head; struct data1; } data_struct_1; typedef struct { struct head; struct data2; } data_struct_2; 如果布尔值为真,则应使用数据结构2,否则应使用数据结构1。当创建对象并将其作为membervariable存储在构造函数中时,将传递布尔值 现在有不同的函数和声明,如 i

我有一个具有不同功能的类。此类使用两个typedef结构

typedef struct {
   struct head;
   struct data1;
} data_struct_1;

typedef struct {
   struct head;
   struct data2;
} data_struct_2;
如果布尔值为真,则应使用数据结构2,否则应使用数据结构1。当创建对象并将其作为membervariable存储在构造函数中时,将传递布尔值

现在有不同的函数和声明,如

int calc_mean(data_struct_1 ds, int a){ ... }

有没有一种优雅的方法,可以让我在这两个结构之间切换,而无需实现几十个if情况,并用头中相应的结构复制所有相关函数? 首先我考虑的是继承和覆盖相关函数,如果bool是真的。。但是函数中的头不同,所以这不起作用
可能有占位符或模板之类的东西,但我对c++还是比较陌生。

如果布尔值是编译时值,可能会用到:

template <boolean B>
using my_type = std::conditional_t<B, data_struct_1, data_struct_2>;

如果布尔值是编译时值,则可以使用:

template <boolean B>
using my_type = std::conditional_t<B, data_struct_1, data_struct_2>;

您有两个选择:

  • 如果这些类型在概念上是同一类型的事物(即它们具有相同的接口并且可以相互替换),则可以:
  • 创建抽象基类型并使用多态性更改实例化的具体类型
  • 将所有使用这些类型的地方都更改为模板,更改在运行时实例化的模板,然后依靠编译时的“duck typing”完成其余工作
  • 如果类型在概念上不同(即它们不应具有相同的接口),则可以使用联合类型(
    union
    ,)

  • 您有两个选择:

  • 如果这些类型在概念上是同一类型的事物(即它们具有相同的接口并且可以相互替换),则可以:
  • 创建抽象基类型并使用多态性更改实例化的具体类型
  • 将所有使用这些类型的地方都更改为模板,更改在运行时实例化的模板,然后依靠编译时的“duck typing”完成其余工作
  • 如果类型在概念上不同(即它们不应具有相同的接口),则可以使用联合类型(
    union
    ,)
  • 一种可能性是使用:

    一种可能性是使用:

    看一看

    一个变体可以包含许多替代类型,如下所示:

    std::variant<data_struct_1, data_struct_2> m;
    
    std::变体m;
    
    成员
    m
    可以包含
    数据结构1
    数据结构2
    变体将记住哪个,因此您无需再随身携带
    bool

    现在有趣的问题是,在函数中如何处理
    m
    ?毕竟,它可以是
    数据结构1
    数据结构2
    。与使用分支来区分这些情况不同,
    variant
    使用:每当您在函数中遇到依赖于
    m
    中存储的具体类型的点时,将该代码移动到两个重载函数中:一个函数处理
    数据结构1
    案例,另一个函数处理
    数据结构2
    案例。上的示例显示了使用不同程度的语法开销来实现这一点的一些可能性

    这种方法的好处在于,它迫使您始终正确处理这两种情况。您不能只为一种情况编写一个实现,然后忘记另一种情况,让它稍后在运行时崩溃。它还鼓励您将代码的公共部分与特定于类型的部分明确地分开,这通常会带来更干净的长期设计

    一个变体可以包含许多替代类型,如下所示:

    std::variant<data_struct_1, data_struct_2> m;
    
    std::变体m;
    
    成员
    m
    可以包含
    数据结构1
    数据结构2
    变体将记住哪个,因此您无需再随身携带
    bool

    现在有趣的问题是,在函数中如何处理
    m
    ?毕竟,它可以是
    数据结构1
    数据结构2
    。与使用分支来区分这些情况不同,
    variant
    使用:每当您在函数中遇到依赖于
    m
    中存储的具体类型的点时,将该代码移动到两个重载函数中:一个函数处理
    数据结构1
    案例,另一个函数处理
    数据结构2
    案例。上的示例显示了使用不同程度的语法开销来实现这一点的一些可能性


    这种方法的好处在于,它迫使您始终正确处理这两种情况。您不能只为一种情况编写一个实现,然后忘记另一种情况,让它稍后在运行时崩溃。它还鼓励您将代码的公共部分与特定类型的部分明确分开,这通常会带来更干净的长期设计。

    简单的C解决方案是一个带有
    bool
    标记的
    union

      typedef struct {
        struct head;
        bool type_flag;
        union{
            struct data1 d1;
            struct data2 d2
        };
      } data_struct;
    
    std::variant
    对于这种情况来说是一种过度杀伤力。继承和运行时多态性是对运行时和内存的浪费

    问候,,
    FM.

    简单的C解决方案是一个带有
    bool
    标记的
    union

      typedef struct {
        struct head;
        bool type_flag;
        union{
            struct data1 d1;
            struct data2 d2
        };
      } data_struct;
    
    std::variant
    对于这种情况来说是一种过度杀伤力。继承和运行时多态性是对运行时和内存的浪费

    问候,,
    FM.

    如果两个结构中有不同的字段,那么它们也应该是派生结构的一部分,而不是基结构的一部分。通常,如果两个类非常相似,那么它们应该是(1)相同基类的子类,或者(2)相同类模板的实例化(或者两者都是)。如果不了解更多关于您的特定用例的信息,就很难判断您应该做什么。这是def吗
      typedef struct {
        struct head;
        bool type_flag;
        union{
            struct data1 d1;
            struct data2 d2
        };
      } data_struct;