如果函数在类范围内声明,则constexpr不起作用 [英] constexpr not working if the function is declared inside class scope

查看:235
本文介绍了如果函数在类范围内声明,则constexpr不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

int main(){}

然而,如果我将变量在 class 中作为 static ,然后给出编译器错误

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

int main(){}

这是错误:
$ b


错误:array'array'的大小不是整型常量表达式

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

解决方案

是的,它是不合格的。这是为什么:

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

例如:

  constexpr int f(); //声明f 
constexpr int x = f(); //使用f - ILLEGAL,f未定义
constexpr int f(){return 5; } //定义f,太迟

类定义符中的函数定义(以及初始值和默认值参数)基本上按照它们在类之外定义的顺序进行解析。



所以这个:

  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; }

也就是说,函数体的解析直到类说明符被破坏。 b
$ b

推迟函数体解析的目的是让函数体能够转发尚未在此时声明的引用类成员,并且也可以使用它们自己的类作为完整类型:

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

与命名空间范围相比:

  void f(){T t; / *错误,T未声明* /} 
typedef int T;

POINT A ,编译器不会' t的定义是 size(),所以它不能调用它。编译时性能 constexpr 函数需要在编译期间被调用之前在翻译单元中使用之前进行定义,否则编译器将不得不多次传递给链接常量表达式进行评估。


I am using g++4.8.0, which doesn't contain earlier constexpr bug. Thus below code works fine:

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

int main () {}

However, if I enclose both the variable inside a class as static, then it gives compiler error:

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

int main () {}

Here is the error:

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

Is it forbidden to use constexpr in such a way or yet another g++ bug?

解决方案

Yes, it is ill-formed. Here's why:

A constexpr function needs to be defined (not just declared) before being used in a constant expression.

So for example:

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

function definitions inside a class specifier (as well as initializers and default parameters) are essentially parsed in an order like they were defined outside the class.

So this:

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

Is parsed in this order:

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

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

That is, parsing of function bodies are defered until after the class specifier.

The purpose of this deferral of function body parsing is so that function bodies can forward reference class members not yet declared at that point, and also so they can use their own class as a complete type:

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

Compared to at namespace scope:

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

At POINT A, the compiler doesn't have the definition of size() yet, so it can't call it. For compile-time performance constexpr functions need to be defined ahead of their use in the translation unit before being called during compile, otherwise the compiler would have to make a multiple passes just to "link" constant expressions for evaluation.

这篇关于如果函数在类范围内声明,则constexpr不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆