是否可以在头部声明 conexpr 类并在单独的. cpp 文件中定义它?

我有一个类 Dimension,我定义了它(像我所有的类一样)在一个维数.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) {}

但是当我尝试使用这个类时,编译器告诉我:

警告: 使用内联函数‘ constexpr 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 文件,一切正常。

我使用的是 GCC 4.9.2。为什么单独的定义不起作用?

24269 次浏览

If a constexpr function is not defined inside the header, the compiler can not see the definition of the constexpr functions while compiling all the other source files.

Obviously, if it can't see the definition of the functions, it can't perform the steps necessary to calculate them at compile-time. Thus all constexpr functions must be defined everywhere they are used.

Thanks @IgorTandetnik:
[dcl.constexpr] §7.1.5/2

constexpr functions and constexpr constructors are implicitly inline.

[basic.def.odr] §3.2/4

An inline function shall be defined in every translation unit in which it is odr-used.

What you're asking can be accomplished, with a significant limitation: the constexpr function can then only be called from inside the translation unit (i.e. source file) where it is defined. This is not appropriate for the example you gave, since the constructor is meant to be part of the class' public interface. However it can be very useful in other cases, e.g. to define private methods as constexpr and then use their return values in expressions that need to be known at compile time, e.g. template instantiations, switch statement labels, etc.