我正在为以下代码中的 #define
寻找可移植的单行替换。替换应该在 Foo
对象的命名空间中隐藏单词 APPLE
。
class Foo {
public:
#define APPLE 123
Foo(int a) : a_(a) { }
};
// elsewhere in another file
Foo f(APPLE);
我试图使它对 C++ 更友好,并且它使用 Intel 2017 编译器工作:
class Foo {
public:
static constexpr int APPLE = 123;
Foo(int a) : a_(a) { }
};
// elsewhere
Foo a(Foo::APPLE);
但它不适用于 g++ ((GCC) 6.3.1 20170216),因为它给出了错误
undefined reference to Foo::APPLE
因为它可能正在尝试引用 APPLE
。
我知道我可以通过在 *.cpp 文件中创建定义来“解决”问题
constexpr int Foo::APPLE;
但这违反了我将 #define
替换为 1 行的理想。我的 Foo
类只是头文件,现在我需要一个 cpp
文件来定义 Foo::APPLE
。我知道我也可以将 APPLE 声明为一个函数 (static constexpr int APPLE() {return 123;}
) 但这需要在声明中输入更多内容,并且在每个使用点我都需要使用 ()
调用函数。
使用 #define
似乎更容易完成。非静态 const int
工作正常,但 APPLE
不能用作构造函数的参数。也许有一个很好的理由说明这在 C++ 中是不可能的。
编辑:这不是 Undefined reference to static constexpr char[] 的拷贝.该问题与字符串以及出现特定错误消息的原因有关。我试图避免一起使用静态链接(我在问题中承认我知道如何进行静态链接)并且我想以“更好/更清洁”的方式进行,我从答案中看到了这种方式通过我的标准的是使用 enum
。
最佳答案
您已经在问题中列出了大多数备选方案。您需要考虑要采用哪种方法:
- 使用需要 C++17 的内联变量(你的第一次尝试在这个标准中隐式工作)
- 在源文件中定义你不想做的静态成员
- 改用内联静态成员函数,您也不希望这样
- 使用命名空间作用域的 constexpr 变量而不是成员
- 使用成员枚举:
enum : int { APPLE = 123 };
- 使用宏(不要选择这个)
关于C++ 等价于整数的#define,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52883934/