C ++ const中的临时对象确实是?

时间:2011-01-15 19:08:48

标签: c++ const temporary

我一直认为C ++中的临时对象会被编译器自动视为const。但最近我遇到了以下代码示例:

function_returning_object().some_non_const_method();

对C ++编译器有效。它让我想知道 - 是C ++ const中的临时对象吗?如果是,那么为什么编译器认为上面的代码是正确的?

6 个答案:

答案 0 :(得分:6)

不,他们不是。除非您将返回类型声明为const。

答案 1 :(得分:5)

取决于。

int f();
const int g();

class C { };
C x();
const C y();

对于f()g(),返回的值不是const,因为没有非类型的const限定rvalues。返回类型const中的g()完全没用(实际上,它比无用更糟糕,因为它在极少数情况下会导致模板实例化问题)。

x()的情况下,返回的值不是const(因为它不是const限定的)。在y()的情况下,返回的值是const(因为返回类型是const限定的)。此处的const限定符(或缺少限定符)是有意义的,因为返回类型是类类型。

答案 2 :(得分:5)

首先回答这个问题,它们实际上不是常量。您不能将其绑定到非const引用。这可能是为了防止在某些情况下出现错误,这些错误将作为参数传递给修改它们的函数,仅用于对临时对象而不是预期目标进行更改。

当您希望使用局部变量调用“swap”时,允许对临时文件执行非常量操作特别有用。

std::vector<T> local;
method_that_returns_a_vector().swap( local );

在移动语义的日子之前,这被认为是返回大型数据集并获取它而不复制所有数据的最有效方式。

答案 3 :(得分:2)

临时对象可以是const,但它们不一定是。

((string const)"hello").append(" world"); // error!

它允许各种各样的事情。考虑

struct bitref {
  int index;
  bitref &operator=(bool value); // non-const!
};

struct bitset {
  int flags;
  // returns a bitref temporary that's associated with the bit
  // at index 'index'. 
  bitref operator[](int index); 
  // ...
};

你可以做到

bitset b;
b[1] = true; // change second bit to 1

这是std::bitset<>模板所做的。

答案 4 :(得分:2)

临时对象不是const,但它们只能绑定到const lvalue引用。很容易证明,允许临时数据绑定到非常量左值引用几乎在所有情况下都会受到影响。你也不能拿一个临时的地址,即使你可以绑定它的引用,还有一些其他非常愚蠢的事情发生在C ++ 03中的临时性。很高兴C ++ 0x很快就会到来......希望如此。

答案 5 :(得分:0)

这一切都取决于函数的返回类型。

//Temporary objects: nameless objects that are only usable in current statement
Object function();           //Return a temporary object by value (using copy constructor)
const Object function();     //Return a const temp object by value

//references, return a reference to an object existing somewhere else in memory
Object & function();         //Return an object reference, non-const behaves as any other non-const
const Object & functon();    //Return const obj reference, behaves as any other const