使用宏进行动态版本选择

Posted

技术标签:

【中文标题】使用宏进行动态版本选择【英文标题】:Dynamic version selection with macros 【发布时间】:2018-09-26 03:14:20 【问题描述】:

我在我的代码中使用了第 3 方库,我正在尝试测试它的最新版本。我的其他同事使用的是旧版本,我应该提交适用于两个版本的代码。 现在的问题是,我正在使用的函数在 2 个版本中具有不同数量的参数。

//eg- in ver_old
DoSomething(para 1, para 2);
//ver_new
DoSomething(para 1, para 2, para 3 , para 4);

如果我按照ver_new修改代码,有旧代码的就不能编译,如果我用ver_old,我就不能编译代码。库中有一个函数可以将版本作为 *char 返回。

有没有办法可以使用#if #else #endif 来选择要编译的方法?或者使用带有#define 的版本字符?

谢谢。

编辑 - 我将无法编辑库中的代码。

【问题讨论】:

您可以为新添加的参数设置默认值,以便新旧参数都能正常工作。恕我直言,使用宏使代码在两个版本中都能正常工作是作弊(顺便说一句,“动态”和“宏”通常不能很好地结合在一起) 我想这个库提供了一个宏来告诉版本号,所以你可以在上面使用#if。否则你必须在你身边创建等价物。 【参考方案1】:

您可以在较新的库中实现两个版本,因此您只有一个只有两个参数。它可以调用较新的版本,为缺少的参数提供一些默认值。

【讨论】:

【参考方案2】:

您的问题可能不够清楚,但这是获得答案的重要提示:

库中有一个函数可以将版本作为 *char 返回。

甚至在您的代码被编译之前,宏就会被扩展。您无法根据函数的返回值进行条件编译(您只能在运行时调用它)。

如果您的代码应该适用于旧版本和新版本,您需要寻找不同的解决方案。对于其他参数,您可以提供默认值:

foo(int x, double y);              // old

foo(int x, double y, float z = 0); // new

【讨论】:

【参考方案3】:

您可以强制调用者使用#define 一个宏,例如#define NEW_LIB,然后在新代码中使用#ifdef。如果已定义,则使用新版本,否则使用旧版本。

否则,仅供参考,C兼容的替代函数重载:

typedef struct

  int    a;
  char   b;
  double c;
  char*  d;
 new_param_list;

void DoSomethingNew (new_param_list* list);

#define DoSomething(...) DoSomethingNew(&(new_param_list) __VA_ARGS__ )

如果传递了 2 个参数,则其他 2 个将设置为零。

对于不支持复合字面量的 C++ 编译器,宏同样可以调用构造函数 new_param_list(int a, char b, double c, char* d) 来获取匿名临时对象。

【讨论】:

以上是关于使用宏进行动态版本选择的主要内容,如果未能解决你的问题,请参考以下文章

如何选择要在 Ruby 中动态包含的模块版本?

没有宏的 C++ 配置方法

每一行视觉选择的 Vim 宏

如何在 Xcode Profiling and Archiving Builds 中设置 DEBUG 和 NDEBUG 宏?

按标题选择一列并使用宏 ROUND 到最近的一分钱

在Excel中动态选择当前列中的筛选行数