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

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

问题描述:

我有一个类 Dimension ,我在文件Dimension.h中定义了该类(就像我的所有类一样):

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;

};

我认为我可以像所有班级一样,将定义放在单独的Dimension.cpp中:

I thought I could, like in all my classes, put the definition in a separate 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:

警告:内联函数' constexpr Dimension :: Dimension()'已使用但从未定义

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

,并且在链接时:

对' 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;

};

并忽略.cpp文件,一切正常。

and omit the .cpp file, everything works fine.

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

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

如果 constexpr 函数是没有在标头中定义,编译器在编译所有其他源文件时看不到 constexpr 函数的定义。

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.

很显然,如果看不到函数的定义,则无法在编译时执行计算它们所需的步骤。因此,所有 constexpr 函数都必须在使用它们的任何位置进行定义。

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.

感谢@IgorTandetnik:

[dcl.constexpr]§7.1.5/ 2

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


constexpr 函数和 constexpr 构造函数是隐式内联的。

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.