C++中特殊的临时变量
C++中产生的临时变量主要产生于计算表达式中间, 函数传参或者返回时候的类型转换中间, 旧一点的书上说在C++中产生的临时变量默认的是const
的, 很容易让人产生混乱。先说结论, C++中间的临时变量并不是const
的,之所以大家有这样的困惑大概是经常能碰到下面的这段代码:
void f(int &x){}
void g(const int &x){}
int h(){}
int main() {
//f(h()); // (1) cannot compile
g(h()); // (2) successfully compile
}
抛开教科书的内容,可以很自然的想到, h()返回了一个临时变量, 如果这个临时变量不是const
属性, 编译器为什么要拒绝编译(1)的代码呢, 相反(2)的代码可以成功通过编译。但是紧接着有人举出下面的反例:
struct Foo {
void f();
}
Foo g(){};
int main() {
g().f();//g() get a Foo class, which has f() method
}
如果临时变量是const
属性的, 那么它怎么可以调用自己的非const的方法呢, 是编译器撒了谎么?
这就是C++中临时变量的特殊性, 它的行为一边像const变量, 一边又像普通变量。其实我这样说本身就有问题, 因为像刚开始说的结论那样, C++中的临时变量本身就不是const属性的,之所以出现第一个例子中的这种情况,是因为语言标准规定:
… C++ doesn’t want you to accidentally modify temporaries, but directly calling a non-const member function on a modifiable rvalue is explicit, so it’s allowed …
意思是不能将临时变量绑定到非const引用上, 如果这样做有可能会改变该临时变量的数据,很多情况下这不是程序员的初衷, 所以禁止这样做。