模板参数,#define和代码重复

时间:2010-09-01 06:11:29

标签: c++ templates code-duplication

我有很多像这样的代码:

#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&lt; 0&gt; :: f()和A&lt; 1&gt; :: f()几乎复制A :: f()的整个代码,仅仅依赖于几行参数。我也不想调用函数而不是之前的#ifdefs。什么是常见的解决方案?

4 个答案:

答案 0 :(得分:2)

如果您想避免重复功能f的逻辑,可以使用template method pattern(不,不是那种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
    }
};

答案 1 :(得分:1)

我相信你想要的东西等同于D语言中存在的“static 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
};

答案 2 :(得分:0)

常见的解决方案就是使用#ifdef我很害怕。 : - )

答案 3 :(得分:0)

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