C ++设计:具有布尔选项的函数

时间:2012-10-03 19:17:00

标签: c++ boolean flags

我在C ++中有一个“好的设计实践”的问题。我正在用C ++ 11编写一个数值库,我使用了大量的元编程和基于模板的技术。但我有一个非常基本的问题:

考虑一个可以有两个非常接近的行为的函数,除了可以通过布尔标志激活的选项。我只考虑开发人员可以设置/取消设置的标志,而不是可以在运行时设置/取消设置的标志。设计有三种可能性:


1)在名称中使用explicit选项编写两个函数:

myFunctionFlag1(...);
myFunctionFlag2(...); 

2)使用模板参数:

template<bool Flag> myFunction(...);

3)使用变量参数:

myFunction(..., const bool flag);

在良好的设计实践方面,哪种解决方案可接受/不可接受?如果有最佳解决方案,那是哪一个?为什么?如果有一个最糟糕的解决方案,那是什么?为什么?

编辑:对于所考虑的函数,运行时开销可以被认为是微不足道的,因此这不是最关键的一点。

编辑2:我知道所有这三项工作。但由于我的图书馆将拥有用户,因此需要有可靠/优秀的设计。

选项2是否常见(因为在我看来这是一个很好的折衷方案)?

5 个答案:

答案 0 :(得分:11)

以上都不是。布尔标志对于代码可读性来说很糟糕。如果标志控制的功能足够小以至于使用单个函数是有意义的,那么使用单个函数,但不要使用bool作为标志的类型。而是使用具有有用名称的枚举器的枚举:

enum class MyFunctionMode { EnableFoo, DisableFoo };

void myFunction(..., MyFunctionMode mode);

这种模式使得在呼叫站点易于理解为该功能提供了哪些选项。可以使用标志组合多个选项。

答案 1 :(得分:2)

我的建议是使用选项1。

评论:

  1. 最简单明了。它没有运行时开销。
  2. 我没有看到足够的理由(如果给出更多细节可能仍然存在)使用这种方法。它比选项1更复杂。
  3. 此变体具有运行时间开销。它仍然可以在非时间/ CPU关键代码中使用。如果你的功能很大(超过100行),那么这个变体会变得更有吸引力,
  4. 我的2美分。

答案 2 :(得分:0)

你的第一个解决方案重复了代码,这是没有人愿意做的事情。

第三个是可以接受的,但是if语句将在运行时进行评估,并意味着时间浪费。

模板似乎是合适的。 if语句在编译时将为if (true)if (false),编译器将对其进行优化,就好像它们不是if语句一样。

答案 3 :(得分:0)

你可以做你知道的所有三个。

void fun_that_does_stuff();
void fun_that_does_something_else();

template < bool F >
void fun_that_does_stuff_or_something();
template < >
void fun_that_does_stuff_or_something<true>() { fun_that_does_stuff(); }

... blah blah.

答案 4 :(得分:0)

复制非平凡代码是最糟糕的选择。如果这两个函数只是执行调度到实际有趣的函数,它可能是正确的选项。当然,这两个函数可以调度到模板化版本,但它们可以更好地指示与truefalse之间的差异。

另一个问题是如何实际使用这些函数:如果它们本身是从具有相同配置或配置的函数调用的,可以从中导出标记的选择,使用不同的名称变得相当烦人甚至无法维护:你会最终必须有条件地调用函数:

(flag? &myFunctionFlag1: &myFunctionFlag2)(...);

其他两个版本之间的选择可以解决这个问题:检查是否重要?如果是,模板是唯一的选择。如果没有,你可以选择任何一个版本,我敢打赌,一个匿名民意调查会投票给运行时版本:当我向他们展示一个简单的模板时,我的大多数同事都会瞪大眼睛。