7

我有很多这样的代码:

#define WITH_FEATURE_X

struct A {
#ifdef WITH_FEATURE_X
  // ... declare some variables Y
#endif
  void f ();
};

void A::f () {
  // ... do something
#ifdef WITH_FEATURE_X
  // ... do something and use Y
#else
  // ... do something else
#endif
  // ... do something
}

我想用模板参数替换#defines:

template < int WITH_FEATURE_X > // can be 0 or 1
struct A;

但是我不想只为依赖于参数的几行复制 A<0>::f() 和 A<1>::f() 的 A::f() 的几乎整个代码。我也不想调用函数而不是以前的#ifdefs。常见的解决方案是什么?

4

4 回答 4

2

如果你想避免重复函数的逻辑,f你可以使用模板方法模式(不,不是那种template.

template <bool enabled>
class helper {
protected:
    void foo() { /* do nothing */ }
};

template <>
class helper<true> {
protected:
    Y y;
    void foo() { /* do something with y */ }
};

struct A : private helper<WITH_FEATURE_X> {
    void f() {
        // common stuff

        foo(); // optimized away when WITH_FEATURE_X is false

        // more common stuff
    }
};
于 2010-09-01T07:41:18.350 回答
1

我相信你想要的是相当于 D 语言中存在的“静态 if”命令。恐怕C++中不存在这样的功能。

请注意,如果您的代码的某些部分根据您的请求的功能而有所不同,则这些部分不属于 main 函数,因为它们不是裸算法的一部分。因此,在函数中委派这些特性的选项似乎是一个不错的选择。

编辑
如果您的#ifdef 语句用于以不同方式执行相同的子任务,那么定义子函数是正确的做法。它将使您的代码更具可读性,而不是更少。

如果它们用于完全不同的操作,那么您的代码已经很混乱了。做点什么。

至于您担心可能出现的性能问题,请相信您的编译器。

EDIT2
我忘了提及代码第一部分的答案:使用以下技巧根据“功能”添加或删除成员。

namespace helper
{
  template<int feature>
  struct A;

  template<>
  struct A<0> { // add member variables for case 0 };

  template<>
  struct A<1> { // add member variables for case 1 };
}

template<int feature>
class A : private helper::A<feature>
{
  // ... functions here
};
于 2010-09-01T06:22:27.213 回答
0

常见的解决方案,恐怕只是使用#ifdef。:-)

于 2010-09-01T06:25:17.533 回答
0

我不明白常见的代码重复。如果你使用模板参数,你只是用 if(WITH_FEATURE_X) 替换你的#ifdef。你在谈论编译器的代码膨胀吗?由于您试图替换 #ifdef 我假设您将在任何时候使用 A<0> 或 A<1> 。因此,即使是编译器,我也看不到代码膨胀。

于 2010-09-01T07:16:48.050 回答