考虑以下简单的类,这些类是我根据我在实际项目中看到的问题设计的。constexpr
Triple 是与Foo 类中的内部 s 一起使用的快速样板类型:
#include <iostream>
class Triple {
public:
friend
std::ostream & operator <<(std::ostream & o, Triple const & t);
constexpr Triple() : a_(0), b_(0), c_(0) { }
constexpr Triple(Triple const & other) = default;
constexpr Triple(double a, double b, double c)
: a_(a), b_(b), c_(c)
{ }
~Triple() = default;
private:
double a_, b_, c_;
};
std::ostream & operator <<(std::ostream & o, Triple const & t) {
o << "(" << t.a_ << ", " << t.b_ << ", " << t.c_ << ")";
return o;
}
class Foo {
public:
Foo() : triple_(defaultTriple) { }
Triple const & triple() const { return triple_; }
Triple & triple() { return triple_; }
constexpr static float defaultPOD{10};
constexpr static Triple defaultTriple{11.0, 22.0, 33.0};
private:
Triple triple_;
};
如果我随后编写一个main()
函数来使用来自 的公共内部constexpr
s Foo
,如下所示,它将无法链接(使用 g++ 4.7.0,在 Windows 7 上通过 mingw-x86-64 的方式):
int main(int argc, char ** argv) {
using std::cout;
using std::endl;
cout << Foo::defaultPOD << endl;
cout << Foo::defaultTriple << endl;
}
$ g++ -o test -O3 --std=c++11 test.cpp e:\temp\ccwJqI4p.o:test.cpp:(.text.startup+0x28): undefined reference to `Foo::defaultTriple' collect2.exe: error: ld returned 1 exit status
但是,如果我写
cout << Triple{Foo::defaultTriple} << endl
而不是简单地
cout << Foo::defaultTriple << endl
它将链接并运行良好。我可以看到前者更明确地表达了编译时文字的意图,但我仍然很惊讶后者不能正常工作。这是一个编译器错误,还是基于规则的原因constexpr
,只有第一个示例才能工作?
我会尝试其他编译器以获得更多见解,但目前 GCC 4.7.0 是我唯一可以访问的支持constexpr
.
另请注意,pod 的表达式在constexpr
没有显式文字包装的情况下可以正常工作,例如cout << Foo::defaultPOD
从未给我带来麻烦。