有类似的问题,但我没有发现直接回答这个问题。
我想实现这样的constexpr函数:
constexpr int Foo(int x) {
static const int table[128] = { 3, 1, 4, 1, 5, ..., 99 };
return (0 <= x && x < 128) ? table[x] : 42;
}
我担心如图所示使表函数静态,因为编译器可能会添加昂贵的检查以使表线程的初始化安全(减慢每个调用),并且这些检查可能使优化器不太可能内联这个琐碎的功能。
因此我认为我将表移动到名称空间静态,在一个.cpp文件中定义它,而函数本身仍然在标题中定义,以便它可以内联。
constexpr int Foo(int x) {
extern constexpr int table[];
return (0 <= x && x < 128) ? table[x] : 42;
}
编译器抱怨我无法在constexpr函数中声明table
。所以我试过了:
extern constexpr int table[];
constexpr int Foo(int x) {
return (0 <= x && x < 128) ? table[x] : 42;
}
这是不允许的,因为你不能只声明constexpr,你必须定义它。但是如果我在头文件中定义表,我会违反单定义规则,对吗?
constexpr int table[128] = { 3, 1, 4, 1, 5, ..., 99 };
constexpr int Foo(int x) {
return (0 <= x && x < 128) ? table[x] : 42;
}
我知道Foo没有违反ODR,因为constexpr意味着内联函数定义。编译器接受了这个并且似乎做了正确的事情,但我知道编译器不需要为ODR违规发出诊断。
Q1:在最后一次迭代中,table
是ODR违规吗?
Q2:如果没有,是否有办法阻止table
对包含此标题的每个翻译单元可见?
答案 0 :(得分:0)
不确定Q1(如果您定义table
static
?)但是,对于Q2,我建议将Foo()
作为friend
函数用于{{1}的类}}是table
private
成员。
以示例
static constexpr