有人能想出一种干净,优雅的方法来避免下面两个函数的重复(除了为每个相同的代码块编写辅助函数,还是使用宏)?
void foo (bool b) {
const int num = std::rand() % 5;
// code block A
if (b) {
// code block B
}
else {
// code block C
}
// code block D
const int number = num + 1;
// code block E
}
void bar (bool b) {
const int num = std::rand() % 5;
// code block A
// code block C // code block B not used (bool b used elsewhere though)
// code block D
const int number = num < 10 ? num + 1 : 0;
// code block E
}
一般来说,对待这样的事情最好的方法是什么?
想法:仅处理不同的部分。像
这样的东西enum {Foo, Bar};
template <int N>
struct FooBar {
void operator()(bool b) {
const int num = std::rand() % 5; // Some random number
// code block A
if (b) {
// code block B
}
else {
// code block C
}
// code block D
const int number = get_number(num);
// code block E
}
private:
int number(int) const;
};
template<> int FooBar<Foo>::get_number (int num) const {return num + 1;}
template<> int FooBar<Bar>::get_number (int num) const {return num < 10 ? num + 1 : 0;}
答案 0 :(得分:3)
将foo和bar组合成一个带有两个参数的函数:bool b
,bool q
。 q
的值将决定此新函数的行为是否与foo或bar相同。
答案 1 :(得分:2)
如果在两个单独的函数中有两个相同的代码片段,唯一的方法来摆脱重复是将它们放在一个新函数(当然,还是一个宏)中。
既干净又优雅。那就是你应该做的。
答案 2 :(得分:0)
只是抛出一个似乎有用的想法。不确定它是否过于激进。其他人会这样做吗?
enum {Foo, Bar};
template <int N>
struct FooBar {
void operator()(bool b) const {
const int num = std::rand() % 5; // Some random number
// code block A
check_bool(b);
// code block D
const int number = get_number(num);
// code block E
}
private:
int get_number(int) const;
void check_bool (bool b) const;
void code_block_c() const {
// code block C
}
};
template<> void FooBar<Foo>::check_bool (bool b) const {
if (b) {
// code block B
}
else
code_block_c();
}
template<> int FooBar<Foo>::get_number (int num) const {return num + 1;}
template<> void FooBar<Bar>::check_bool (bool) const {code_block_c();}
template<> int FooBar<Bar>::get_number (int num) const {return num < 10 ? num + 1 : 0;}
void foo (bool b) {FooBar<Foo>()(b);}
void bar (bool b) {FooBar<Bar>()(b);}
int main() {
for (int i = 0; i < 100000000; i++) {
foo(true); bar(true);
foo(false); bar(false);
}
}
// 5.548 seconds
// The following alternative results in no time difference really:
//FooBar<Foo> foo_;
//FooBar<Bar> bar_;
//void foo (bool b) {foo_(b);}
//void bar (bool b) {bar_(b);}
建议使用另一个bool参数:
void foo_bar (bool b, bool q) {
const int num = std::rand() % 5;
// code block A
if (q) {
if (b) {
// code block B
}
else {
// code block C
}
}
else
// code block C
// code block D
const int number = q ? num + 1 : (num < 10 ? num + 1 : 0);
// code block E
}
void foo (bool b) {foo_bar(b, true);}
void bar (bool b) {foo_bar(b, false);}
int main() {
for (int i = 0; i < 100000000; i++) {
foo(true); bar(true);
foo(false); bar(false);
}
}
// 4.724 seconds
尽管if-checks不断检查,但他们建议的解决方案执行速度要快一些。