为什么常量指针不能是常量表达式? [英] Why can't a constant pointer be a constant expression?

查看:139
本文介绍了为什么常量指针不能是常量表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下程序编译:

template <const int * P>
class Test{};

extern const int var = 42; //extern needed to force external linkage

int main()
{
    Test<&var> test;
}

但是,这不是,这让我感到惊讶:

This one, however, doesn't, which is a surprise for me:

template <const int * P>
class Test{};

extern const int var = 42; //extern needed to force external linkage
extern const int * const ptr = &var; //extern needed to force external linkage
int main()
{
    Test<ptr> test; //FAIL! Expected constant expression.
}

替代示例:

int main()
{
   const int size = 42;
   int ok[*&size]; //OK

   const int * const pSize = &size;
   int fail[*pSize]; //FAIL
}

我已经得出结论,无论指针是否为const并使用常量表达式初始化,指针都不能是常量表达式.

I have concluded that a pointer just can't be a constant expression regardless of whether it's const and initialized with a constant expression.

问题:

  1. 我的结论正确吗?
  2. 如果是这样,为什么指针不能是常量表达式?如果没有,为什么上面的程序不能编译?
  3. C ++ 0x(如果需要,可以使用C ++ 11)更改任何内容吗?

感谢您的见解!

推荐答案

有点复杂.在C ++ 03和C ++ 11中,如果var是本地静态/类静态或名称空间范围变量,则&var是常量表达式.这称为地址常量表达式.可以保证在运行任何代码之前(静态初始化阶段)使用该常量表达式初始化类静态或名称空间作用域指针变量,因为它是一个常量表达式.

It's a bit more complicated. In C++03 and C++11, &var is a constant expression if var is a local static / class static or namespace scope variable. This is called an address constant expression. Initializing a class static or namespace scope pointer variable with that constant expression is guaranteed to be done before any code is run (static initialization phase), because of it being a constant expression.

但是,仅自C ++ 11起,存储地址&var constexpr 指针变量也可以用作地址常量表达式,并且仅自C ++ 11起,您可以取消引用地址常量表达式(实际上,您甚至可以取消引用-甚至包括本地数组元素地址,但让我们保留其在原位),如果它引用的是在取消引用之前初始化的常量整数变量或constexpr变量,则您将再次获得一个常量表达式(根据类型和值类别的不同,常量表达式的类型可能会有所不同).因此,以下是有效的C ++ 11:

However only since C++11, a constexpr pointer variable that stores the address &var can also be used as an address constant expression and only since C++11, you can dereference an address constant expression (actually, you can dereference even more - even local array element addresses, but let's keep it ontopic) and if it refers to a constant integral variable initialized prior to the dereference or a constexpr variable, you again get a constant expression (depending on the type and value category, the kind of constant expression may vary). As such, the following is valid C++11:

int const x = 42;
constexpr int const *px = &x;

// both the value of "px" and the value of "*px" are prvalue constant expressions
int array[*px];
int main() { return sizeof(array); }

如果是这样,为什么指针不能为常量表达式?如果没有,为什么上面的程序不能编译?

If so, why can't a pointer be a constant expression? If not, why don't the above programs compile?

这是标准措辞中的已知限制-对于指针类型的模板参数,当前仅允许将其他模板参数用作参数或& object.即使编译器应该能够做更多的事情.

This is a known limitation in the Standard's wording - it currently only allows other template parameters as arguments or & object, for a template parameter of pointer type. Even though the compiler should be capable of doing much more.

这篇关于为什么常量指针不能是常量表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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