相当于整数的#define的C++

Mar*_*ata 4 c++ c++14

我正在寻找#define以下代码中的便携式一行替代品.替换应该隐藏对象APPLE命名空间中的单词Foo.

class Foo {
public:
#define APPLE 123
    Foo(int a) : a_(a) { }
};

 // elsewhere in another file
    Foo f(APPLE);
Run Code Online (Sandbox Code Playgroud)

我试图使这个更加C++友好,它使用英特尔2017编译器:

class Foo {
public:
    static constexpr int APPLE = 123;
    Foo(int a) : a_(a) { }
};

// elsewhere

    Foo a(Foo::APPLE);
Run Code Online (Sandbox Code Playgroud)

但它不适用于g ++((GCC)6.3.1 20170216),因为它给出了错误

undefined reference to Foo::APPLE
Run Code Online (Sandbox Code Playgroud)

因为它可能试图引用APPLE.

我知道我可以通过在*.cpp文件中创建定义来"解决"问题

constexpr int Foo::APPLE;
Run Code Online (Sandbox Code Playgroud)

但这违反了我#define被1线替换的理想.我的Foo类只是头文件,现在我需要一个cpp文件来定义Foo::APPLE.我知道我也可以将APPLE声明为函数(static constexpr int APPLE() {return 123;}),但是在声明中输入的内容要多得多,而且在每个使用点我都需要调用函数().

使用它#define并完成它似乎更容易.非静态const int工作正常,但APPLE不能用作构造函数的参数.也许有充分的理由说明为什么在C++中这是不可能的.

编辑:这不是对静态constexpr char []未定义引用的重复.该问题与字符串有关,以及为什么会出现特定的错误消息.我试图避免一起使用静态链接(我在我的问题中承认我知道如何进行静态链接)并且我想做一个"更好/更清洁"的方式,我从答案中看到的方式通过我的标准是使用enum.

eer*_*ika 6

您已经在问题中列出了大多数替代方案.您需要考虑要采取的方法:

  • 使用需要C++ 17的内联变量(您的第一次尝试隐含在此标准中)
  • 在源文件中定义静态成员,您不想这样做
  • 请使用内联静态成员函数,这也是您不想要的
  • 使用命名空间范围的constexpr变量而不是成员
  • 使用成员枚举: enum : int { APPLE = 123 };
  • 使用宏(不要选择这个)

  • `enum`方法是唯一适合我的方法.谢谢 (2认同)