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

发布于 2024-09-17 00:14:30 字数 545 浏览 7 评论 0原文

我有很多这样的代码:

#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::f() 的几乎整个代码() 和 A<1>::f() 仅适用于依赖于参数的几行。我也不想调用函数来代替之前的#ifdef。常见的解决方案是什么?

I have a lot of code like this:

#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
}

and I'd like to replace the #defines with template parameters:

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

But I don't want to duplicate almost the entire code of A::f() for A<0>::f() and A<1>::f() just for the few lines that depend on the parameter. I also don't want to call functions instead of the previous #ifdefs. What is the common solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你怎么敢 2024-09-24 00:15:30

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

I don't get the point of common code duplication. If u are using template parameter u are just replacing your #ifdef with if(WITH_FEATURE_X).
Are u talking about code bloat by the compiler.
Since you are trying to replace #ifdef I am assuming you would be using either A<0> or A<1> at any point. So I don't see a code bloat even by the compiler.

素衣风尘叹 2024-09-24 00:15:21

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

The common solution, is just to use #ifdef I'm afraid. :-)

思念绕指尖 2024-09-24 00:15:12

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

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

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

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

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

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

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
};

I believe what you want is an equivalent to the "static if" command that exists in D language. I am afraid such a feature does not exist in C++.

Note that if parts of your code vary depending on the feature your request, these parts don't belong in the main function because they are not part of the bare algorithm. So the option to delegate such features in functions seems like a good one.

EDIT
If your #ifdef statements are used to do the same subtask differently, then defining subfunctions is the right thing to do. It will make your code more readable, not less.

If they are used for completely different actions, well, your code is already cluttered. Do something about it.

As for the performance issue you fear might appear, trust your compiler.

EDIT2
I forgot to mention the answer to the first part of your code : use the following trick to add or remove members depending on "feature".

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
};
转瞬即逝 2024-09-24 00:15:05

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

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
    }
};

If you want to avoid duplicating the logic of function f you can use the template method pattern (no, not that kind of 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
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文