设为首页 加入收藏

TOP

2.4 const Qualifier (5)
2013-10-07 16:18:10 来源: 作者: 【 】 浏览:74
Tags:2.4 const Qualifier

2.4.4 constexpr and Constant Expressions

A constant expression is an expression whose value cannot change and that can be eva luated at compile time. A literal is a constant expression. A const object that is initialized from a constant expression is also a constant expression. As we’ll see, there are several contexts in the language that require constant expressions.

Whether a given object (or expression) is a constant expression depends on the types and the initializers. For example:

  1. const int max_files = 20; // max_files is a constant expression   
  2. const int limit = max_files + 1; // limit is a constant expression   
  3. int staff_size = 27; // staff_size is not a constant expression   
  4. const int sz = get_size(); // sz is not a constant expression  

Although staff_size is initialized from a literal, it is not a constant expression because it is a plain int, not a const int. On the other hand, even though sz is a const, the value of its initializer is not known until run time. Hence, sz is not a constant expression.
constexpr Variables

In a large system, it can be difficult to determine (for certain) that an initializer is a constant expression. We might define a const variable with an initializer that we think is a constant expression. However, when we use that variable in a context that requires a constant expression we may discover that the initializer was not a constant expression. In general, the definition of an object and its use in such a context can be widely separated.

Under the new standard, we can ask the compiler to verify that a variable is a constant expression by declaring the variable in a constexpr declaration. Variables declared as constexpr are implicitly const andmust be initialized by constant expressions:

  1. constexpr int mf = 20; // 20 is a constant expression   
  2. constexpr int limit = mf + 1; // mf + 1 is a constant expression   
  3. constexpr int sz = size(); // ok only if size is a constexpr function  

Although we cannot use an ordinary function as an initializer for a constexpr variable, we’ll see in § 6.5.2 (p. 239) that the new standard lets us define certain functions as constexpr. Such functions must be simple enough that the compiler can eva luate them at compile time. We can use constexpr functions in the initializer of a constexpr variable.

Generally, it is a good idea to use constexpr for variables that you intend to use as constant expressions.

Literal Types

Because a constant expression is one that can be eva luated at compile time, there are limits on the types that we can use in a constexpr declaration. The types we can use in a constexpr are known as “literal types” because they are simple enough to have literal values.

Of the types we have used so far, the arithmetic, reference, and pointer types are literal types. Our Sales_item class and the library IO and string types are not literal types. Hence, we cannot define variables of these types as constexprs. We’ll see other kinds of literal types in § 7.5.6 (p. 299) and § 19.3 (p. 832).

Although we can define both pointers and reference as constexprs, the objects we use to initialize them are strictly limited. We can initialize a constexpr pointer from the nullptr literal or the literal (i.e., constant expression) 0. We can also point to (or bind to) an object that remains at a fixed address.

For reasons we’ll cover in § 6.1.1 (p. 204), variables defined inside a function ordinarily are not stored at a fixed address. Hence, we cannot use a constexpr pointer to point to such variables. On the other hand, the address of an object defined outside of any function is a constant expression, and so may be used to initialize a constexpr pointer. We’ll see in § 6.1.1 (p. 205), that functions may define variables that exist across calls to that function. Like an object defined outside any function, these special local objects also have fixed addresses. Therefore, a constexpr referencemay be bound to, and a constexpr pointer may address, such variables.


Pointers and constexpr

It is important to understand that when we define a pointer in a constexpr declaration, the constexpr specifier applies to the pointer, not the type to which the pointer points:

  1. const int *p = nullptr; // p is a pointer to a const int   
  2. constexpr int *q = nullptr; // q is a const pointer to int  

Despite appearances, the types of p and q are quite different; p is a pointer to const, whereas q is a constant pointer. The difference is a consequence of the fact that constexpr imposes a top-level const (§ 2.4.3, p. 63) on the objects it defines.

Like any other constant pointer, a constexpr pointer may point to a const or a nonconst type:

  1. constexpr int *np = nullptr; // np is a constant pointer to int that is null   
  2. int j = 0;   
  3. constexpr int i = 42; // type of i is const int   
  4. // i and j must be defined outside any function   
  5. constexpr const int *p = &i; // p is a constant pointer to the const int i   
  6. constexpr int *p1 = &j; // p1 is a constant pointer to the int j  

EXERCISES SECTION 2.4.4

Exercise 2.32: Is the following code legal or not If not, how might you make it legal

  1. int null = 0, *p = null;  

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇2.4 const Qualifier (4) 下一篇2.5 Dealing with Types (2)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·用 Python 进行数据 (2025-12-25 15:49:09)
·如何学习Python数据 (2025-12-25 15:49:07)
·利用Python进行数据 (2025-12-25 15:49:04)
·Java 学习线路图是怎 (2025-12-25 15:19:15)
·关于 Java 学习,有 (2025-12-25 15:19:12)