【发布时间】:2017-08-02 09:49:56
【问题描述】:
我有一个程序,我想在运行时而不是编译时选择一组类型(从预定义列表中)。
下面是我想要运行的代码示例; Even 和 Log 是定义数值网格的类型,deriv_Ox 是 x 阶微分方案:
struct Even {
double a, b;
};
struct Log {
double a, x0, b;
};
// ...
struct deriv_O2 {
vec_type operator() (const vec_type & f_points) const;
};
struct deriv_O4 {
vec_type operator() (const vec_type & f_points) const;
};
// ...
template <class grid_type, class deriv_type>
void run_calculation (const std::string param_file) {
auto grid = grid_from_file<grid_type>(param_file);
auto deriv = deriv_from_file<deriv_type>(param_file);
// ...
}
我想通过读取参数文件来决定在运行时使用哪些类型。我的解决方案是使用标签和 case 语句从单个列表中决定使用哪种类型,然后将每个 case 语句嵌套在一个函数中,决定集合中的每种类型,如下所示:
enum struct grid_tag { Even, Log };
enum struct deriv_tag { O4, O2 };
grid_tag grid_tag_from_file (const char file_name[]);
deriv_tag deriv_tag_from_file (const char file_name[]);
template <class deriv_type>
void run_calculation (const grid_tag g,
const std::string param_file) {
switch(g) {
case grid_tag::Even:
run_calculation<Even, deriv_type>(param_file);
break;
case grid_tag::Log:
run_calculation<Log, deriv_type>(param_file);
break;
}
}
void run_calculation (const grid_tag g, const deriv_tag d,
const std::string param_file) {
switch(d) {
case deriv_tag::O4:
run_calculation<deriv_O4>(g, param_file);
break;
case deriv_tag::O2:
run_calculation<deriv_O2>(g, param_file);
break;
}
}
int main (int argc, char * argv[]) {
grid_tag g = grid_tag_from_file(argv[1]);
deriv_tag d = deriv_tag_from_file(argv[1]);
run_calculation(g, d, argv[1]);
}
问题是我有一组 ~6 种类型可以从 ~10 大小的列表中选择,而且这些类型在未来还会增加。我目前的解决方案让添加新类型变得很尴尬。
这个解决方案是我要做的最好的吗?我是不是很挑剔,还是有人可以提出更好的解决方案?我看过 boost::variant (如在类似问题中推荐的那样),但我认为这并不适合我想做的事情。
【问题讨论】:
-
您需要所有 ~10^6 的类型组合吗?听起来很多代码