C++ 使用#define 设置默认参数

C++ set default arguments with #define

我可以将默认参数设置为#defined 值吗?

#define WIDTH 1920
#define HEIGHT 1080

void calculate(int width = WIDTH, int height = HEIGHT) {
    //do stuff
}

可以使用#define。但是你应该吗?

#define 忽略范围,并且有 other problems。此代码同样有效,不会让任何人对不必要的定义感到惊恐。

enum {WIDTH  = 1920 };
enum {HEIGHT = 1080 };

void calculate(int width = WIDTH, int height = HEIGHT) 
{
  //do stuff
}

这也适用:

const int WIDTH  = 1920;
const int HEIGHT = 1080;

void calculate(int width = WIDTH, int height = HEIGHT) 
{
  //do stuff
}

这个也一样,虽然不是很清楚:

void calculate(int width = 1920, int height = 1080) 
{
  //do stuff
}

是的。 WIDTH 和 HEIGHT 宏将扩展为 19201080。这将与 :

void calculate(int width = 1920, int height = 1080) { // ...

根据您的情况,出于不同的原因,您可能更喜欢 static const int 而不是宏,您可以找到 on this answer;或者至少将 WIDTHHEIGHT 重命名为更具体的名称,因为这似乎很容易发生冲突。正如另一个答案所述,使用静态变量的一个优点是它们是有范围的。

C++17 注意:您将能够 to inline a variable。如果编译器在优化阶段t/can没有对 const 执行此操作,您将来可能更喜欢这种方法。

是的,你可以,但如果你能避免,就不要这样做。假设您在 header

中定义了
// foo.h
#define WIDTH 123

并且出于某种原因,您将此 header 包含在其他 header 中,其中包含如下内容:

// bar.h
#include "foo.h"
int bar(int WIDTH) { return WIDTH*2; }

根据我的经验,这会导致非常严重的错误,如果您不使用宏就可以完全避免。

您可能会争辩说大写可以避免此类错误,但是您仍然可以

// moo.h
#define WIDTH 321
#include "foo.h"

这甚至不会导致编译器错误,但更难追踪错误。