【问题标题】:C++ set default arguments with #defineC++ 使用#define 设置默认参数
【发布时间】:2016-09-20 17:56:40
【问题描述】:

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

#define WIDTH 1920
#define HEIGHT 1080

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

【问题讨论】:

  • 这不是默认参数的目的吗?
  • 究竟是什么问题?

标签: c++ default-arguments


【解决方案1】:

可以使用#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
}

【讨论】:

  • 如果它不再是宏,为什么要保持大写?
  • 因为将 const 放在大写字母中是一种惯例 - 可以很容易地看到什么是 const。 stackoverflow.com/questions/838929/…这个有争议。
  • 这不是传统的,它是一个从将常量定义为预处理器宏的坏习惯。出于同样的原因。
  • 有什么理由想让它成为枚举?
  • 对常量使用全部大写的惯例不是来自 C++ 预处理器宏,而是来自 ALGOL(它早于 C),它用于常量。它也用于 Pascal、Ruby、PHP 和其他语言。无论好坏,这是许多语言的有意约定。
【解决方案2】:

是的,你可以,但如果你能避免,就不要这样做。想象一下,您在标题中有定义

// foo.h
#define WIDTH 123

由于某种原因,您将此标头包含在其他包含以下内容的标头中:

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

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

你可能会争辩说大写可以让你避免这样的错误,但是你仍然可以

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

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

【讨论】:

    【解决方案3】:

    是的。 WIDTH 和 HEIGHT 宏将扩展为 19201080。这将与以下内容相同:

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

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

    C++17 注意:你可以to inline a variable。如果编译器在优化阶段不能/不能通过 const 执行此操作,那么您将来可能会更喜欢这种方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-13
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      • 2016-04-25
      • 2019-10-22
      相关资源
      最近更新 更多