我正在寻找以下代码中的#define
的便携式一行替代品。替换应在APPLE
对象的命名空间中隐藏单词Foo
。
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
。
答案 0 :(得分:6)
您已经在问题中列出了大多数替代方案。您需要考虑要采用的方法:
enum : int { APPLE = 123 };
答案 1 :(得分:2)
除了已经提到的内容外,还有“穷人的内联变量”:
static constexpr const int& APPLE = std::integral_constant<int, 123>::value;
您定义一个具有恒定静态数据成员的类模板,该成员的值就是您想要的值。您可以离线定义该静态数据成员-但在标头中,因为它是类模板的静态数据成员。在这种情况下,std::integral_constant
已经做完了所有事情,因此您不必自己编写。
然后,将实际的静态数据成员常量定义为对该类模板静态数据成员的constexpr引用;不需要线外定义,因为不可能odr使用由常量表达式初始化的引用。