Timo Türschmann Timo Türschmann - 2 months ago 23
C++ Question

Is it possible to declare constexpr class in a header and define it in a seperate .cpp file?

I have a class

Dimension
which I defined (like all my classes) in a file Dimension.h:

class Dimension
{
public:

constexpr Dimension() noexcept;

constexpr Dimension(int w, int h) noexcept;

int width;
int height;

};


I thought I could, like in all my classes, put the definition in a seperate Dimension.cpp:

#include "Dimension.h"

constexpr Dimension::Dimension() noexcept : width(0), height(0) {}

constexpr Dimension::Dimension(int w, int h) noexcept : width(w), height(h) {}


But when I try to use the class, the compiler tells me:

warning: inline function '
constexpr Dimension::Dimension()
' used but never defined

and while linking:

undefined reference to '
pong::graphics::Dimension::Dimension()
'

(same with the other constructor)

If I define the class in the header like so:

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;

};


and omit the .cpp file, everything works fine.

I'm using GCC 4.9.2. Why does seperate definition not work?

Answer

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 he can't see the definition of the functions, he 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.