2014-12-07 301 views
21

我有一个文件Dimension.h类Dimension,我定义(如同我所有的类):是否可以在头文件中声明constexpr类并将其定义在单独的.cpp文件中?

class Dimension 
{ 
public: 

    constexpr Dimension() noexcept; 

    constexpr Dimension(int w, int h) noexcept; 

    int width; 
    int height; 

}; 

我以为我可以像在我所有的班,把定义在一个单独的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) {} 

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

警告:使用内联函数“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。为什么单独的定义不起作用?

+7

“constexpr”函数的要点是允许在编译时评估函数。如果编译器无法看到所述函数的主体,那么这将是相当困难的。 – 2014-12-07 17:13:12

+2

_“为什么单独的定义不起作用?” - 因为语言不允许。接受它,正确地做,继续前进。 – 2014-12-07 17:13:14

+0

我已经怀疑过,但我不太确定我是否可以解释(可能是参考)为什么它确切发生。我在Google上搜索时没有发现任何关于此的内容,所以我想出了一个新问题,因为这是合适的。 – 2014-12-07 17:19:28

回答

27

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

很明显,如果它看不到函数的定义,它就不能执行在编译时计算它们所需的步骤。因此,所有constexpr函数都必须在使用它们的任何地方定义。

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

constexpr功能和构造constexpr隐含直列。

[basic.def.odr]§3.2/ 4

内联函数应每翻译单元,其中它是ODR使用的限定。

5

你问可以取得什么成就,有显著限制:constexpr功能就只能从它被定义翻译单元(即源文件)中被调用。这不适用于您给出的示例,因为构造函数旨在成为类的公共接口的一部分。然而,在其他情况下它可能非常有用,例如将私有方法定义为constexpr然后在编译时需要知道的表达式中使用它们的返回值,例如,模板实例化,开关语句标签等。

相关问题