我有一个不同功能的类。 该类使用两个typedef结构。
typedef struct {
struct head;
struct data1;
} data_struct_1;
typedef struct {
struct head;
struct data2;
} data_struct_2;
如果bool为true,则应使用data_struct_2,否则应使用data_struct_1。 当创建对象并将其作为membervariable存储在构造函数中时,将传递布尔值。
现在有不同的函数和声明,如
int calc_mean(data_struct_1 ds, int a){ ... }
或
data_struct_1 ds;
ds.data1 = 5;
有没有一种优雅的方式,可以让我在那两个结构之间切换,而不用实现几十个if-case,并用头中相应的结构复制所有相关的函数? 首先,我考虑的是继承和覆盖相关函数,如果bool为真。 但是函数中的头不同,所以这是行不通的,可能有一些像占位符或模板之类的东西,但是我对C++还是很陌生的
如果布尔值是编译时值,则可以使用std::conditional
:
template <boolean B>
using my_type = std::conditional_t<B, data_struct_1, data_struct_2>;
但布尔值似乎是运行时值,因此我将使用std::variant
和std::visit
:
class C
{
using Data = std::variant<data_struct_1, data_struct_2>;
Data m_data;
public:
C(bool b) : m_data{b ? Data{data_struct_1{}} : Data{data_struct_2{}}} {}
auto mean() const {
return std::visit([](const auto& data){ return int calc_mean(data, 42); }, m_data);
}
};
您有几种选择:
一种可能是使用std::variant
:
typedef std::variant<data_struct_1, data_struct_2> data_struct_1_or_2;
void foo(data_struct_1_or_2 ds) {
if (auto ds1 = std::get_if<data_struct_1>(&ds)) {
// use ds1, which is type data_struct_1*
} else if (auto ds2 = std::get_if<data_struct_2>(&ds)) {
// use d2, which is type data_struct_2*
}
}
void bar(data_struct_1_or_2 ds) {
foo(ds); // Don't need to use an if statement here
}
如果您有一个data_struct_1
或data_struct_2
,并且希望传递对对象的引用,而不是一个副本,则可以使用std::variant
中的指针(尽管它会与std::get_if
有点混淆,因为您最终会得到指向指针的指针):
typedef std::variant<data_struct_1*, data_struct_2*> data_struct_1_or_2_ptr;