C++ 是否可以在头文件中声明constexpr类并在单独的.cpp文件中定义它?
我在文件维度中定义了一个类C++ 是否可以在头文件中声明constexpr类并在单独的.cpp文件中定义它?,c++,c++11,constexpr,C++,C++11,Constexpr,我在文件维度中定义了一个类维度。h: class Dimension { public: constexpr Dimension() noexcept; constexpr Dimension(int w, int h) noexcept; int width; int height; }; 我想我可以像在我所有的课程中一样,将定义放在一个单独的维度中。cpp: #include "Dimension.h" constexpr Dimension::D
维度
。h:
class Dimension
{
public:
constexpr Dimension() noexcept;
constexpr Dimension(int w, int h) noexcept;
int width;
int height;
};
我想我可以像在我所有的课程中一样,将定义放在一个单独的维度中。cpp:
#include "Dimension.h"
constexpr Dimension::Dimension() noexcept : width(0), height(0) {}
constexpr Dimension::Dimension(int w, int h) noexcept : width(w), height(h) {}
但当我尝试使用该类时,编译器告诉我:
警告:已使用内联函数“constepr Dimension::Dimension()
”,但从未定义
链接时:
对“pong::graphics::Dimension::Dimension()”的未定义引用
(与其他构造函数相同)
如果我在标题中这样定义类:
class Dimension
{
public:
constexpr Dimension() noexcept : width(0), height(0) {}
constexpr Dimension(int w, int h) noexcept : width(w), height(h) {}
int width;
int height;
};
省略.cpp文件,一切正常
我使用的是GCC4.9.2。为什么单独的定义不起作用?如果头中没有定义constepr
函数,编译器在编译所有其他源文件时无法看到constepr
函数的定义
显然,如果它看不到函数的定义,它就不能在编译时执行计算这些函数所需的步骤。因此,所有constexpr
函数必须在使用它们的任何地方定义
谢谢@IgorTandetnik:
[dcl.constexpr]§7.1.5/2
constexpr
函数和constexpr
构造函数是隐式内联的
[basic.def.odr]§3.2/4
应在使用odr的每个翻译单元中定义内联函数
您的要求可以实现,但有一个明显的限制:constexpr函数只能从定义它的翻译单元(即源文件)内部调用。这不适用于您给出的示例,因为构造函数是类的公共接口的一部分。但是,它在其他情况下非常有用,例如将私有方法定义为constexpr,然后在编译时需要知道的表达式中使用它们的返回值,例如模板实例化、开关语句标签等。constexpr
函数的整个要点是允许在编译时对函数进行求值。如果编译器看不到所述函数的主体,这将是相当困难的。我已经怀疑过了,但我不太确定我是否能解释(可能是引用)它发生的确切原因。我在谷歌搜索时没有发现任何关于这一点的信息,所以我想一个新问题是合适的。@TimoTürschman“但我不太确定我是否能解释(可能有参考)它为什么会发生…”改写@IgorTandetnik的评论:编译器需要看到一个constepr
hc在使用时完全展开,将正确的表达式插入到位。链接阶段太晚了。如果你坚持章节:7.1.5/2constexpr
函数和constexpr
构造函数是隐式内联的。3.2/4应在使用odr的每个翻译单元中定义内联函数。