我Dimension在一个文件Dimension.h中定义了一个类(比如我的所有类):
class Dimension
{
public:
constexpr Dimension() noexcept;
constexpr Dimension(int w, int h) noexcept;
int width;
int height;
};
Run Code Online (Sandbox Code Playgroud)
我认为我可以像在所有类中一样将定义放在一个单独的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) {}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用该类时,编译器会告诉我:
警告:内联函数' 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;
};
Run Code Online (Sandbox Code Playgroud)
并省略.cpp文件,一切正常.
我正在使用GCC 4.9.2.为什么单独的定义不起作用?
Tim*_*ann 48
如果constexpr未在头部内定义函数,则编译器constexpr在编译所有其他源文件时无法看到函数的定义.
显然,如果它看不到函数的定义,它就无法在编译时执行计算它们所需的步骤.因此,constexpr必须在使用它们的任何地方定义所有功能.
谢谢@IgorTandetnik:
[dcl.constexpr]§7.1.5/ 2
constexpr函数和constexpr构造函数是隐式内联的.
[basic.def.odr]§3.2/ 4
内联函数应在每个使用它的翻译单元中定义.
Yit*_*ikC 10
您所要求的可以完成,但有一个显着的限制:constexpr函数只能从定义它的转换单元(即源文件)内部调用.这不适用于您提供的示例,因为构造函数应该是类的公共接口的一部分.但是在其他情况下它可能非常有用,例如将私有方法定义为constexpr,然后在需要在编译时知道的表达式中使用它们的返回值,例如模板实例化,switch语句标签等.