c++ const 引用赋值错误

march_on 2013-06-26 04:53:35
代码如下:

int ival = 1024;
int* pival = &ival;
int*& sdf = pival; //正确
const int*& pi_ref = pival;//错误,为什么
const int* const& pi_ref = pival;//正确

错误信息:

error: invalid initialization of reference of type 'const int*&' from expression of type 'int*'


请问为什么错误呢,我在codeblocks下用gcc编译的。
...全文
326 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
march_on 2013-06-30
  • 打赏
  • 举报
回复
分太少了,不够给力,抱歉
march_on 2013-06-30
  • 打赏
  • 举报
回复
引用 15 楼 quarryman 的回复:
我做的笔记,希望有用: 1)一维指针和简单引用 T => T & T => T const T* => T const * T* => T * const T* => T const * const T => T const & T& => T const & 测试代码:没有错误

int main()
{
	int  i=0;
	// T  => T &
	int* p=&i;
	int& r=i;
	
	// T  => T const
	int const ic=i;
	// T* => T const *
	int const * pic=p;
	// T* => T * const
	int * const cpi=p;
	// T* => T const * const
	int const * const cpci=p;

	// T  => T const &
	int const& rci=i;
	// T& => T const &
	int const& rci2=r;

	return 0;
}
2)二维指针和指针的引用 从右往左看,=>表示可以转化,!=>表示不能转化 T** => T * const * => T const * const * T*& => T * const & => T const * const & T* => T * const & => T const * const & T** !=> T const ** T*& !=> T const *& 证明: typedef P T*; 因为:T* => T const * 和 T& => T const & P* => P const * 即:T** => T * const * P& => P const & 即:T*& => T * const & 又因为:T => T const 或 T* => T const * T * const * => T const * const * T * const & => T const * const & 测试代码:

int main()
{
	int   i=0;
	int*  p=&i;
	int** pp=&p;
	int*& rp=p;

	// T**  => T * const *
	int * const * pcpi=pp;
	// T**  => T const * const *
	int const * const * pcpci=pp;
	// T*&  => T * const & 
	int * const & rcpi=rp;
	// T*&  => T const * const &
	int const * const & rcpci=rp;
	// error C2440: 'initializing' : cannot convert from 'int **' to 'const int **'
	int const ** ppci=pp;
	// error C2440: 'initializing' : cannot convert from 'int *' to 'const int *&'
	int const *& rpci=rp;
	
	return 0;
}
嗯,总结的很好,多谢
采石工 2013-06-30
  • 打赏
  • 举报
回复
我做的笔记,希望有用: 1)一维指针和简单引用 T => T & T => T const T* => T const * T* => T * const T* => T const * const T => T const & T& => T const & 测试代码:没有错误

int main()
{
	int  i=0;
	// T  => T &
	int* p=&i;
	int& r=i;
	
	// T  => T const
	int const ic=i;
	// T* => T const *
	int const * pic=p;
	// T* => T * const
	int * const cpi=p;
	// T* => T const * const
	int const * const cpci=p;

	// T  => T const &
	int const& rci=i;
	// T& => T const &
	int const& rci2=r;

	return 0;
}
2)二维指针和指针的引用 从右往左看,=>表示可以转化,!=>表示不能转化 T** => T * const * => T const * const * T*& => T * const & => T const * const & T* => T * const & => T const * const & T** !=> T const ** T*& !=> T const *& 证明: typedef P T*; 因为:T* => T const * 和 T& => T const & P* => P const * 即:T** => T * const * P& => P const & 即:T*& => T * const & 又因为:T => T const 或 T* => T const * T * const * => T const * const * T * const & => T const * const & 测试代码:

int main()
{
	int   i=0;
	int*  p=&i;
	int** pp=&p;
	int*& rp=p;

	// T**  => T * const *
	int * const * pcpi=pp;
	// T**  => T const * const *
	int const * const * pcpci=pp;
	// T*&  => T * const & 
	int * const & rcpi=rp;
	// T*&  => T const * const &
	int const * const & rcpci=rp;
	// error C2440: 'initializing' : cannot convert from 'int **' to 'const int **'
	int const ** ppci=pp;
	// error C2440: 'initializing' : cannot convert from 'int *' to 'const int *&'
	int const *& rpci=rp;
	
	return 0;
}
飞天御剑流 2013-06-27
  • 打赏
  • 举报
回复
引用 12 楼 march_on 的回复:
[quote=引用 7 楼 supermegaboy 的回复:] 楼上说的都有点问题,其实楼主发生的问题与大家熟知的const int **与int**之间的转换问题并不是同一类问题,两者是不同的情况。 const int*& pi_ref = pival;不行是因为从int*到const int*的转换需要产生一个临时对象,但pi_ref属于非const对象的引用,大家都知道非const对象的左值引用是不能用右值进行初始化的,这是常识。因此上述语句不能通过编译,pi_ref引用的类型加上const后,才能引用右值,所以const int* const& pi_ref = pival;才是正确的。 楼主提出的问题与下述现象才是同一类问题:

int & r0 = 20.0;  //失败
const int & r1 = 20.0; //成功
1.从int*到const int*的转换需要产生一个临时对象, 这句话是不是说pi_ref 引用的不是pival,而是pival隐式转化为const int*类型后的临时对象?像4楼plainsong说的那样? 2.pi_ref属于非const对象的引用, 这句话不是很理解,const int*& pi_ref = pival; pi_ref引用的是一个指向整型常量的指针,你说pi_ref属于非const对象的引用是指它引用的指针不是常量指针,虽然这个指针指向的是一个整型常量(const int),是这个意思吧? 加上一个const后变成const int* const& pi_ref = pival; 这句话的意思是pi_ref引用的是一个指针常量,这个指针不可以修改,然后这个指针指向的是一个整型常量。是这样吗?这个新加的const是说引用是const的还是指针是const的呢? 3.pi_ref引用的类型加上const后,才能引用右值 这里pival不是右值,你说的右值是不是我第一个问题里面的临时变量,如果是这样,c++的临时变量是右值,是这样吗 多谢了[/quote] 1、是的。 2、是的,新加的const修饰的是指针,不是引用,const引用是不存在的,因为引用本身是不可修改的。此外,虽然常量的说法不正确,但不影响你对此问题的理解。 3、是的。注意你提到的临时变量是错误的,不存在临时变量,因为变量一定是有名字的,正确的术语叫临时对象。
march_on 2013-06-27
  • 打赏
  • 举报
回复
引用 7 楼 supermegaboy 的回复:
楼上说的都有点问题,其实楼主发生的问题与大家熟知的const int **与int**之间的转换问题并不是同一类问题,两者是不同的情况。 const int*& pi_ref = pival;不行是因为从int*到const int*的转换需要产生一个临时对象,但pi_ref属于非const对象的引用,大家都知道非const对象的左值引用是不能用右值进行初始化的,这是常识。因此上述语句不能通过编译,pi_ref引用的类型加上const后,才能引用右值,所以const int* const& pi_ref = pival;才是正确的。 楼主提出的问题与下述现象才是同一类问题:

int & r0 = 20.0;  //失败
const int & r1 = 20.0; //成功
1.从int*到const int*的转换需要产生一个临时对象, 这句话是不是说pi_ref 引用的不是pival,而是pival隐式转化为const int*类型后的临时对象?像4楼plainsong说的那样? 2.pi_ref属于非const对象的引用, 这句话不是很理解,const int*& pi_ref = pival; pi_ref引用的是一个指向整型常量的指针,你说pi_ref属于非const对象的引用是指它引用的指针不是常量指针,虽然这个指针指向的是一个整型常量(const int),是这个意思吧? 加上一个const后变成const int* const& pi_ref = pival; 这句话的意思是pi_ref引用的是一个指针常量,这个指针不可以修改,然后这个指针指向的是一个整型常量。是这样吗?这个新加的const是说引用是const的还是指针是const的呢? 3.pi_ref引用的类型加上const后,才能引用右值 这里pival不是右值,你说的右值是不是我第一个问题里面的临时变量,如果是这样,c++的临时变量是右值,是这样吗 多谢了
march_on 2013-06-27
  • 打赏
  • 举报
回复
引用 11 楼 mujiok2003 的回复:
看看这个

int *p;
const int *&r = p;    // reference to a pointer to const int
const int immutable = 0;
r = &immutable;    // assign p to address of immutable
*p = 1;    // whoops, now 0 = 1!
如果把r定义成const int * const& r,那么r就是一个const 引用,它用p初始化后就不能再用其他变量对他赋值,就是说此时r=&immutable这句代码就会出错?是这样吗 另外,C++primer51页说const引用就是指向const对象的引用,const int*&r不是一个const引用,是因为r引用的指针不是const指针,比如定义

const int*p;//这个不是const指针,虽然指向的是const对象
const int* const p1;//这个才是const指针
是这样吗
mujiok2003 2013-06-26
  • 打赏
  • 举报
回复
看看这个
橡木疙瘩 2013-06-26
  • 打赏
  • 举报
回复
引用 8 楼 mujiok2003 的回复:
你把我的 (int*) const&换成了 ((int const)*)&
原来你是说后面那个不合法,我还以为你说的是前面的。 后面的确实不合法,因为括号放错了位置。但是int * const &是合法的。 int * const & r = p; 相当于: int ( * const ( & r ) ) = p; 它是一个引用,引用的是一个常量指针,指针指向int可变量。它是用来引用 PINT const类型变量的。

   int a;
   int * const p = &a;
   int * const & r1 = p;
   int ( * const ( & r2 ) ) = p;
芥末的无奈 2013-06-26
  • 打赏
  • 举报
回复
引用 7 楼 supermegaboy 的回复:
楼上说的都有点问题,其实楼主发生的问题与大家熟知的const int **与int**之间的转换问题并不是同一类问题,两者是不同的情况。 const int*& pi_ref = pival;不行是因为从int*到const int*的转换需要产生一个临时对象,但pi_ref属于非const对象的引用,大家都知道非const对象的左值引用是不能用右值进行初始化的,这是常识。因此上述语句不能通过编译,pi_ref引用的类型加上const后,才能引用右值,所以const int* const& pi_ref = pival;才是正确的。 楼主提出的问题与下述现象才是同一类问题:

int & r0 = 20.0;  //失败
const int & r1 = 20.0; //成功
这个回答简洁正确。
mujiok2003 2013-06-26
  • 打赏
  • 举报
回复
引用 6 楼 u010936098 的回复:
[quote=引用 5 楼 mujiok2003 的回复:] const int*& 没有被理解为(int*) const&[这种写法也是不合法的].用typedef解决问题.

int main()
{
  int a = 0;
  int* p = &a;
  typedef int* IP;
  IP const& rp = p;
  return 0;
}
const int * & 确实没有被解释为(int*) const &,但它是合法的:

const int a;
const int * p = a;
const int * & r = p;
//它相当于:
int const ( * ( & r ) ) = p;
//r 是一个引用,它引用的是一个指针,指针指向一个int const变量。
//用typedef 来解释它就是:
typedef int const cint;
typedef cint * pcint;
typedef pcint & rpcint;
rpcint r = p;
[/quote] 你把我的 (int*) const&换成了 ((int const)*)&
飞天御剑流 2013-06-26
  • 打赏
  • 举报
回复
楼上说的都有点问题,其实楼主发生的问题与大家熟知的const int **与int**之间的转换问题并不是同一类问题,两者是不同的情况。 const int*& pi_ref = pival;不行是因为从int*到const int*的转换需要产生一个临时对象,但pi_ref属于非const对象的引用,大家都知道非const对象的左值引用是不能用右值进行初始化的,这是常识。因此上述语句不能通过编译,pi_ref引用的类型加上const后,才能引用右值,所以const int* const& pi_ref = pival;才是正确的。 楼主提出的问题与下述现象才是同一类问题:

int & r0 = 20.0;  //失败
const int & r1 = 20.0; //成功
橡木疙瘩 2013-06-26
  • 打赏
  • 举报
回复
引用 5 楼 mujiok2003 的回复:
const int*& 没有被理解为(int*) const&[这种写法也是不合法的].用typedef解决问题.

int main()
{
  int a = 0;
  int* p = &a;
  typedef int* IP;
  IP const& rp = p;
  return 0;
}
const int * & 确实没有被解释为(int*) const &,但它是合法的:

const int a;
const int * p = a;
const int * & r = p;
//它相当于:
int const ( * ( & r ) ) = p;
//r 是一个引用,它引用的是一个指针,指针指向一个int const变量。
//用typedef 来解释它就是:
typedef int const cint;
typedef cint * pcint;
typedef pcint & rpcint;
rpcint r = p;
mujiok2003 2013-06-26
  • 打赏
  • 举报
回复
const int*& 没有被理解为(int*) const&[这种写法也是不合法的].用typedef解决问题.

int main()
{
  int a = 0;
  int* p = &a;
  typedef int* IP;
  IP const& rp = p;
  return 0;
}
短歌如风 2013-06-26
  • 打赏
  • 举报
回复
此外,

const int* const& pi_ref = pival;//正确 
这里要注意,pi_ref引用的并不是pival,而是由它隐式转换而来的int const *,从语法逻辑上讲,这里应该产生一个类型为int const *的临时对象,pi_ref引用这个对象。为了保证pi_ref的有效性,这个本应在这条语句结束后就释放的临时对象生命期被延长到与pi_ref相同。 如果输出pi_ref的地址和pival的地址,你会发现它们是不同的。 不过,这只是逻辑上的概念,或许某个编译器会把pival和临时对象优化为同一个,毕竟pi_ref是个const reference,这就代表着它是只读的。尽管编译器这样做是错误的,但我们也不能期待它永远守规矩,我们所能做的就是自己要守规矩,不要去const_cast。
短歌如风 2013-06-26
  • 打赏
  • 举报
回复
T * 是一个 T const *, T & 是一个 T const & 但是T ** 不是一个 T const **,T * &也不是一个T const * & T ** 是一个T * const *,T * &是一个T * const & 上面说的“是一个”意思就是可以隐式转换。 第一个,不用说了,大家都明白,non-const指针/引用可以转换为const指针引用 第二个,很久以前我们就讨论过:

int * a;
int const * b;
int const ** c = &a;//假如这一步允许的话
*c = b; //现在a就等于b,我们成功地把一个int const *赋值给了一个int**,没有任何另人警惕的强制类型转换。
上面两个赋值,后面那个肯定不能禁止 ,否则会让指针失去存在意义,所以第一个赋值被禁止,T **不允许隐式转换为T const **
第三个(我列出来的,不是楼主的代码): typedef P = T*; T**就是P*, T*const *就是P const *,又回到了第一条。 最后再看楼主的最后一行代码: const int* const& pi_ref = pival;//正确 pival类型是int*,pi_ref类型比较复杂,我们可以定义一下: typedef int* PInt; typedef int const * PCInt; PInt可以 隐式转换为PCInt; pi_ref是PCInt const & pival是PInt,可以隐式转换为PCInt。 现在清楚了,为了支持函数参数中用const reference代替值拷贝,C++允许 对象A隐式转换为B的传给B const &类型。这里有一个隐式类型转换,由pival转换为PCInt然后赋值给PCInt const &类型的pi_ref 注意,const是左结合 的它修饰的是它左边的类型,当它在最左时才修饰右边,所以const int与int const是等价的。我一般为了清晰,都写后一种。 此外,我现在的系统很慢,输入法的响应远跟不上我输入的速度,所以会有多空格 、少字、少标点的情况 请大家谅解。
AndyStevens 2013-06-26
  • 打赏
  • 举报
回复
我给一个CU上的链接 http://bbs.chinaunix.net/thread-4086492-1-1.html
AndyStevens 2013-06-26
  • 打赏
  • 举报
回复
有点类似于C专家编程里讲述的const int ** 的问题。
int a = 0;
const int *cpa = &a; //正确
int *pa = &a;
const int **cppa = &pa; //错误

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧