sky*_*ack 4 c++ static stl-algorithm constexpr c++11
这是一个问题,其原因对我来说很模糊,但幸运的是,解决方法很容易。
考虑以下代码(让我称其为 my main.cpp):
#include <algorithm>
struct Foo {
static constexpr float BAR = .42;
float operator()() const noexcept {
float zero = .0;
return std::min(zero, BAR);
}
};
int main() {
Foo foo;
foo();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,出现错误:
foobar:~/stackoverflow$ g++ -std=c++11 main.cpp
/tmp/ccjULTPy.o: 在函数 'Foo::operator()() const':
main.cpp:(.text._ZNK3FooclEv[_ZNK3FooclEv] +0x1a):对‘Foo::BAR’的未定义引用
collect2:错误:ld 返回 1 个退出状态
如果我使用以下语句,也会发生同样的情况(很明显):
return std::min(zero, Foo::BAR);
Run Code Online (Sandbox Code Playgroud)
下面是上面示例的稍微修改的版本。
这个编译没有错误,即使我仍然指的是BAR成员:
#include <algorithm>
struct Foo {
static constexpr float BAR = .42;
float operator()() const noexcept {
float zero = .0;
float bar = BAR;
return std::min(zero, bar);
}
};
int main() {
Foo foo;
foo();
}
Run Code Online (Sandbox Code Playgroud)
我没有成功理解为什么后一个版本编译得很好,而前一个版本以错误结束。
据我所知,这两个版本都是正确的,应该可以编译,但我强烈怀疑我在这里遗漏了一些重要的东西。
有什么建议吗?
这是我的编译器版本:g++ (Debian 5.3.1-5) 5.3.1 20160101.
所选择的原型为minIS
template<class T>
/* constexpr since C++14 */ const T& min( const T& a, const T& b );
Run Code Online (Sandbox Code Playgroud)
相关的一点是它通过引用获取参数,这意味着它使用单一定义规则 (ODR)。
而且您从未定义过它,您只是在您的类中声明了它(使用初始化程序):
static constexpr float BAR = .42;
Run Code Online (Sandbox Code Playgroud)
这对于复制和以其他方式使用该值已经足够了,但不能将它用作除纯右值之外的任何东西。
请参阅为什么 constexpr 静态成员(类类型)需要定义?
不需要诊断违反 ODR(其更精细的点确实很细且数量庞大):
3.2 一个定义规则[basic.def.odr]
4 每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的一个定义;无需诊断。定义可以显式地出现在程序中,可以在标准或用户定义的库中找到,或者(在适当的时候)它是隐式定义的(参见 12.1、12.4 和 12.8)。内联函数应在每个使用 odr 的翻译单元中定义。
| 归档时间: |
|
| 查看次数: |
322 次 |
| 最近记录: |