【发布时间】:2016-04-10 20:09:28
【问题描述】:
这是一个问题,其原因对我来说很模糊,但幸运的是,解决方法很简单。
考虑以下代码(让我称之为我的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();
}
当我试图编译它时,我得到了错误:
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);
下面是上述示例的略微修改版本。
这个编译没有错误,即使我仍然指的是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();
}
我没有成功理解为什么后一个版本可以正常编译而前一个版本以错误结束。
据我所知,这两个版本都是正确的,应该可以编译,但我强烈怀疑我在这里遗漏了一些重要的东西。
有什么建议吗?
这里是我的编译器版本:g++ (Debian 5.3.1-5) 5.3.1 20160101。
【问题讨论】:
-
std::min,通过引用取参数,ODR-使用静态成员,需要对应定义 -
有趣,三个 cmets,三种不同的方法。 Nathan,它不是我使用的编译器,反正很有趣。 Piotr,从你的角度来看,我没有完全理解这个问题,你能更详细一点吗? R.Sahu:浮点问题?实际上,在处理浮点变量时,我在实际代码中也遇到了错误......
-
@skypjack 你只声明了一个静态 constexpr 成员,你没有定义它。但是,要将它传递给
std::min,它必须有一个地址(因为它是通过引用获取的)。如果您只将其值分配给局部变量,那么它是一个左值到右值的转换,它不使用 ODR-使用静态数据成员,因此它可以工作
标签: c++ c++11 static constexpr stl-algorithm