c++ - 如果函数在类范围内声明,则 constexpr 不起作用

标签 c++ c++11 compiler-errors g++ constexpr

我使用的是 g++4.8.0,它不包含早期的 constexpr 错误。因此下面的代码工作fine :

constexpr int size() { return 5; }
int array[size()];

int main () {}

但是,如果我将两个变量都包含在 class 中作为 static,那么它会给出 compiler error :

struct X {
  constexpr static int size() { return 5; }
  static const int array[size()]; 
};

int main () {}

这是错误:

error: size of array ‘array’ is not an integral constant-expression

是否禁止以这种方式使用 constexpr 或另一个 g++ 错误?

最佳答案

是的,它的格式不正确。原因如下:

constexpr 函数在用于常量表达式之前需要定义(而不仅仅是声明)。

例如:

constexpr int f(); // declare f
constexpr int x = f(); // use f - ILLEGAL, f not defined
constexpr int f() { return 5; } // define f, too late

类说明符内的函数定义(以及初始化程序和默认参数)本质上是按照它们在类外定义的顺序进行解析的。

所以这个:

struct X {
  constexpr static int size() { return 5; }
  static const int array[size()]; 
};

按此顺序解析:

struct X {
   constexpr inline static int size(); // function body defered
   static const int array[size()];  // <--- POINT A
};

constexpr inline int X::size() { return 5; }

也就是说,函数体的解析被推迟到类说明符之后。

延迟函数体解析的目的是为了使函数体可以转发当时尚未声明的引用类成员,并且它们可以将自己的类作为一个完整类型使用:

struct X
{
    void f() { T t; /* OK */ }
    typedef int T;
};

与在命名空间范围内相比:

void f() { T t; /* error, T not declared */ }
typedef int T;

POINT A处,编译器还没有size()的定义,所以无法调用。为了编译时性能,constexpr 函数需要在编译期间被调用之前在翻译单元中使用之前定义,否则编译器将不得不进行多次传递以“链接”常量表达式评估。

关于c++ - 如果函数在类范围内声明,则 constexpr 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16493652/

相关文章:

java - 如何在 protobuf 中定义循环?

c++ - 将整数引用值转换为 (const char*) 有什么影响,在 C++ 中转换为 char* 和转换为 const char* 有什么区别?

c++ - 专门针对模板类的 C++ 类成员函数

c++ - 用户注销/登录后创建托盘图标时出现罕见错误

c++ - Qcheckbox 在 QT -c++ 中始终选中至少一个选项

c++ - 来自 Valgrind 的令人困惑的输出显示间接丢失的内存泄漏,但没有绝对丢失或可能丢失

c++ - 对参数依赖查找和友元函数定义的混淆

c++ - 错误 : opencv2/core/core. hpp:没有那个文件或目录

go - 语法错误 : unexpected name, 需要分号或换行符或 }

c++ - 在 C++ 代码中包含头文件的更好方法是什么?