天天看点

c++11的constexpr关键字 literal(常量)

a constant expression is an expression whose value can’t change and that can be evaluated at a compile time. a literal is a constant expression.

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

const int max_files = ; // max_files is a constant expresion
int staff_size = ; //staff_size is not a constant expression
const int sz = get_size(); //sz is not a constant expression
           

对于staff_size,尽管初始化值(initializer)是一个literal,但是它本身是一个plain int, not a const int,所以staff_size不是一个constant exprssion.

而对于sz来说,它的initializer的值在编译的时候才能够确定,所以sz不是一个constant expression.

in a large system, it can be difficult to determine for certain that an initializer is a constant expression.

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.

c++primer上举的几个例子是这样

constexpr int mf = ; // 常量表达式  
constexpr int limit = mf + ; // 常量表达式  
constexpr int sz = size(); // 如果size()是常量表达式则编译通过,否则报错  
           

我自己试了一下:

int size()
{
        return -;
}
int main()
{
        constexpr int sz = size();
        return ;
} 
           
xiahuixia@xiahuixia-Inspiron-:~/c++/primercode$ g++ -o constexpr constexpr.cpp -std=c++0x
           

结果是:

constexpr.cpp: In function ‘int main()’:
constexpr.cpp::: error: call to non-constexpr function ‘int size()’
  constexpr int sz = size();
                          ^
           

再来看看这个literal这个英文的意思,有点晦涩

c++primer是这样解释的:

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 self-defined class type and the library IO and string types are not literal types. hence, we can’t define variables of these types as constexprs.

也就是说我们自定义的类和IO库还有字符串不是literal type类型。

为什么呢?且拿我们自定义的类来说吧。

比如说

class a{
int i;
char c;
}
a my_a;
my_a.i = ....
my_a.c = ....
           

类a的成员值在声明的时候或许根本没有初始化。所以不能称得上是literal type.(暂时我还不确定我的假设是不是正确的)