输入库参数的正确方法

时间:2014-10-16 19:47:38

标签: c++ preprocessor-directive

我正在编写一个带有一个小函数库的Matrix类。

该课程能够实现渴望和懒惰的评估。我希望用户选择该课程是否总是渴望,或者如果可能的话,它是否会变得懒惰。

问题:是否有提供此输入的标准方法?

我没有太多的经验,所以我还没有真正看到标准库或者其他人是否(以及如何)这样做。可能使用的方式可能是:

  1. 拥有一个静态全局变量,并为用户提供一种设置其值的方法。
  2. 检查预处理程序指令,如果已定义或未确定要编译的类的代码。
  3. 其他???

1 个答案:

答案 0 :(得分:1)

我假设这是一个仅限标题的模板库。

如果您只想提供全局切换(而不是每个表达式选择),这似乎是合理使用宏开关。我可能会设计库,以便用户可以

#define GREAT_LIBRARY_DISABLE_LAZY_EVALUATION
#include <great_library/matrix.hpp>

甚至

$ cxx -DGREAT_LIBRARY_DISABLE_LAZY_EVALUATION file.cpp

当然,你应该将更通用的选项作为默认选项,如果用户没有选择任何内容,则不会抛出错误。

但是,只有在定义或未定义的宏不会改变库的类型和功能的有效使用时,这才有用。如果您的用户在定义宏之后发现他们最初工作的代码导致编译器错误页面,他们可能会感到不安。

因此,如果它不是一个“不可见”的开关(即影响性能但不影响整个程序的语义),你最好在每个使用点提供细粒度控制。

也许您的模板采用可选参数。

great_lib::Computer<great_lib::EvaluationPolicy::Eager> eager_one;
great_lib::Computer<great_lib::EvaluationPolicy::Lazy> lazy_one;
auto some_result = eager_one.compute(arg1, ..., argN);
auto some_other_result = lazy_one.compute(arg1, ..., argN);

或使用tag dispatching

auto some_result = great_lib::compute(arg1, ..., argN, great_lib::eager_tag);
auto some_other_result = great_lib::compute(arg1, ..., argN, great_lib::lazy_tag);

最后,我认为不像

great_lib::set_evaluation(gerat_lib::EvaluationPolicy::Eager);
auto some_result = great_lib::compute(arg1, ..., argN);
great_lib::set_evaluation(gerat_lib::EvaluationPolicy::Lazy);
auto some_other_result = great_lib::compute(arg1, ..., argN);

在模板化的C ++库中非常有用。您真的希望您的编译器只生成用户选择的任何选项所需的代码,但如果这取决于运行时值,则必须为两个变量生成代码(以及在运行时选择它们的条件) -时间)。更糟糕的是,您可能需要某种形式的运行时多态,我们通常会在高性能C ++代码中避免这种多态。