使用c ++ 11重复代码
我目前正在进行一个项目,我有以下问题。
我有一个C ++方法,我想以两种不同的方式工作:
void MyFunction()
{
foo();
bar();
foobar();
}
void MyFunctionWithABonus()
{
foo();
bar();
doBonusStuff();
foobar();
}
我想不重复我的代码,因为实际功能更长。 问题是我不能在任何情况下在调用MyFunction而不是MyFunctionWithABonus时为程序添加执行时间。 这就是为什么我不能只用一个C ++比较来检查布尔参数。
我的想法是使用C ++模板来虚拟复制我的代码,但我想不出一种做法,我没有额外的执行时间,也不必复制代码。
我不是模板专家,所以我可能会错过一些东西。
你们有没有想法? 或者,这在C ++ 11中是不可能的?
使用模板和lambda,你可以这样做:
template <typename F>
void common(F f)
{
foo();
bar();
f();
foobar();
}
void MyFunction()
{
common([](){});
}
void MyFunctionWithABonus()
{
common(&doBonusStuff);
}
否则你可以创建prefix
和suffix
函数。
void prefix()
{
foo();
bar();
}
void suffix()
{
foobar();
}
void MyFunction()
{
prefix();
suffix();
}
void MyFunctionWithABonus()
{
prefix();
doBonusStuff();
suffix();
}
像这样的事情会很好地做到:
template<bool bonus = false>
void MyFunction()
{
foo();
bar();
if (bonus) { doBonusStuff(); }
foobar();
}
通过以下方式致电
MyFunction<true>();
MyFunction<false>();
MyFunction(); // Call myFunction with the false template by default
通过为函数添加一些漂亮的包装可以避免“丑陋”模板:
void MyFunctionAlone() { MyFunction<false>(); }
void MyFunctionBonus() { MyFunction<true>(); }
你可以在那里找到关于那种技术的一些很好的信息。 这是一个“老”的论文,但这项技术本身保持完全正确。
假如你可以访问一个很好的C ++ 17编译器,你甚至可以推进这项技术,通过使用constexpr来实现,就像这样:
template <int bonus>
auto MyFunction() {
foo();
bar();
if constexpr (bonus == 0) { doBonusStuff1(); }
else if constexpr (bonus == 1) { doBonusStuff2(); }
else if constexpr (bonus == 2) { doBonusStuff3(); }
else if constexpr (bonus == 3) { doBonusStuff4(); }
// Guarantee that this function will not compile
// if a bonus different than 0,1,2,3 is passer
else { static_assert(false);},
foorbar();
}
鉴于OP对调试的一些评论,这里有一个版本调用doBonusStuff()
进行调试构建,但不是发布构建(定义NDEBUG
):
#if defined(NDEBUG)
#define DEBUG(x)
#else
#define DEBUG(x) x
#endif
void MyFunctionWithABonus()
{
foo();
bar();
DEBUG(doBonusStuff());
foobar();
}
如果你想检查一个条件,你也可以使用assert
宏,如果它是假的,就会失败(但只适用于调试版本;发布版本不会执行检查)。
doBonusStuff()
有副作用时要小心,因为这些副作用不会出现在发布版本中,并且可能会使代码中的假设失效。