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/2
constexpr
函数和
constexpr
构造函数是隐式内联的。3.2/4应在使用odr的每个翻译单元中定义内联函数。