C++20 标准 (N4860) 中哪里规定内联函数必须在翻译单元中使用之前定义?

Joh*_*ane 0 c++ inline c++20 constexpr-function

[dcl.constexpr]/1 :

说明constexpr符仅应用于变量或变量模板的定义或者函数或函数模板的声明。说明consteval符仅适用于函数或函数模板的声明。constexpr使用or说明符声明的函数或静态数据成员consteval隐式是内联函数或变量 ([dcl.inline])。如果函数或函数模板的任何声明具有constexprconsteval说明符,则其所有声明都应包含相同的说明符。

实施例1

constexpr void square(int &x);  // OK, declaration
constexpr int bufsz = 1024;     // OK, definition
constexpr struct pixel {        // error: pixel is a type
  int x;
  int y;
  constexpr pixel(int);         // OK, declaration
};
constexpr pixel::pixel(int a)
  : x(a), y(x)                  // OK, definition
  { square(x); }
constexpr pixel small(2);       // error: square not defined, so small(2) <<<<<<<<<<<<<<<<<<<<
                                // not constant ([expr.const]) so constexpr not satisfied

constexpr void square(int &x) { // OK, definition
  x *= x;
}
constexpr pixel large(4);       // OK, square defined
int next(constexpr int x) {     // error: not for parameters
     return x + 1;
}
extern constexpr int memsz;     // error: not a definition
Run Code Online (Sandbox Code Playgroud)

我认为上面用字符突出显示的错误与 [dcl.constexpr]/1 中的第三句<<<<<<<<<<<<<<<有关,即:

使用 constexpr 或 consteval 说明符声明的函数或静态数据成员隐式是内联函数或变量 ([dcl.inline])。

但我在 C++20 (N4860) 中找不到任何可以建立内联函数在翻译单元中使用之前必须定义的断言的内容。

use*_*522 5

constexpr pixel small(2);格式错误,因为声明的变量的初始化constexpr应为常量表达式,并且如果在表达式中调用未定义的 constexpr 函数,则根据[expr.const]/5.3,该表达式将被取消为常量表达式的资格。在您的情况下,对squareinsmall构造函数调用的调用是原因。

没有很好地指定何时需要定义函数(请参阅CWG issues 2166),但无论是合理的解释,square在您的示例中都没有在相关点之前定义,该点要么是调用本身的词汇点,要么是常量表达式本身(即 atsmall的定义)的词法点。


这是具体的后果constexpr,与无关inline。内联函数在翻译单元中使用之前通常不必定义。它只需要在翻译单元中的某个地方定义即可。