16

我听说临时对象只能分配给常量引用。

但是这段代码给出了错误

#include <iostream.h>    
template<class t>
t const& check(){
  return t(); //return a temporary object
}    
int main(int argc, char** argv){

const int &resCheck = check<int>(); /* fine */
typedef int& ref;
const ref error = check<int>(); / *error */
return 0;
}

得到的错误是invalid initialization of reference of type 'int&' from expression of type 'const int'

4

5 回答 5

21

这个:

typedef int& ref;
const ref error;

不做你认为它做的事。改为考虑:

typedef int* pointer;
typedef const pointer const_pointer;

的类型const_pointerint* const不是 const int *。也就是说,当您说const T“创建一个 T 不可变的类型”时;所以在前面的例子中,指针(不是指针)是不可变的。

不能做参考constvolatile。这个:

int& const x;

是没有意义的,所以在引用中添加 cv-qualifiers 没有效果。

因此,error具有类型int&。您不能为其分配 a const int&


您的代码中还有其他问题。例如,这肯定是错误的:

template<class t>
t const& check()
{
    return t(); //return a temporary object
}

您在这里所做的是返回对临时对象的引用,该对象在函数返回时结束其生命周期。也就是说,如果你使用它,你会得到未定义的行为,因为在引用处没有对象。这并不比:

template<class t>
t const& check()
{
    T x = T();
    return x; // return a local...bang you're dead
}    

更好的测试是:

template<class T>
T check()
{
    return T();
}

该函数的返回值是一个临时值,因此您仍然可以测试您确实可以将临时值绑定到常量引用。

于 2010-09-27T08:06:22.610 回答
8

由于英语语法的运作方式,这对于说英语的人来说是一个非常常见的错误。

我认为 C++ 语法允许两者都非常不幸:

const int // immutable int
int const // immutable int

具有相同的含义。

它并没有让它变得更容易,真的,而且是不可组合的,因为:

const int* // mutable pointer to immutable int
int* const // immutable pointer to mutable int

当然没有相同的含义。

正如@GMan 解释的那样,这对你来说很不幸,这里发生了什么。

如果您希望将来避免此类错误,请养成在其右侧const限定类型 (和) 的习惯,那么您将能够将简单的文本替换视为简单的文本替换。volatiletypedef

于 2010-09-27T08:27:39.347 回答
7

你的代码给出了错误,因为const限定符 inconst ref error被忽略了,因为8.3.2/1

cv 限定引用格式错误,除非通过使用 typedef (7.1.3) 或模板类型参数 (14.3) 引入 cv 限定符,在这种情况下忽略 cv 限定符

所以没有error类型。int&const int&

于 2010-09-27T08:07:49.170 回答
3

为了保持与Right Left Rule的一致性,我更喜欢像这样使用 'cv' 限定符。

int const x = 2; // x is a const int (by applying Right Left rule)

int const *p = &x;  // p is a pinter to const int

在你的例子中,我会这样const ref error = check<int>();

ref const error = check<int>(); // parsed as error is a const reference to an integer

正如@Prasoon Saurav 指出的那样,通过 typedef 引入 cv 限定符时会被忽略,因为正如@GMan 还所说,cv 限定引用格式不正确。

因此,声明实际上如下,这当然是一个错误。

   int &error = check<int>(); 

查看以获取更多信息。

于 2010-09-27T08:28:39.153 回答
0

这是编译的:

typedef const int& ref;
参考错误 = 检查<int>();

VC++ 编译器对你的错误给出了一些解释: qualifier applied to reference type; 忽略。引用类型必须声明为常量,以后不能应用 const。

于 2010-09-27T08:08:20.340 回答