C++资格转换 - const限定符

3

有人能解释一下为什么第二个转换是允许的,而第一个不允许吗?它们都可能允许修改const左值...

double *wPtr;
const double ** wRef = &wPtr;
const double * const * wRef = &wPtr;

谢谢,regu。
添加来自Comeau的编译错误...
int main( int argc, const char* argv[] )
{
    double *wPtr;
    const double ** wRef = &wPtr;
    return 0;
}

Compiling Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 4: error: a value of type "double **" cannot be used to
      initialize an entity of type "const double **"
  const double ** wRef = &wPtr;
                         ^

1 error detected in the compilation of "ComeauTest.c".

你能否提供编译代码时出现的错误消息示例吗?我想可能还有其他问题... - Anton
@antonm:不,他说的第一个确实是明显的编译错误,而第二个则不是。他只是对第二个的暗示理解得不太正确。 - Nicholas Knight
@Nicholas:是的,我现在看到了。有人(你?)曾经发布了一个答案,但我现在看不到了。它包含了这个有用的链接:http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17。 - Anton
@antonm:我在修正它的时候不小心把它删了。我刚醒来,解释有点混乱。:) 现在已经恢复了。 - Nicholas Knight
那个链接已经失效了,所以这里再次提供:https://isocpp.org/wiki/faq/const-correctness#constptrptr-conversion - Elliot
2个回答

2
因为第二个例子不允许修改一个常量左值(至少不是在你付出实际努力(强制类型转换,这本身就往往是一个危险的迹象)之前)。我不确定你为什么认为它可以,因为你没有提供进一步的解释。
const double * const * wRef = &wPtr;

你必须非常仔细地阅读这篇文章。它说“wRef是一个指向const double的const指针的指针”。
你可以修改wRef(使其指向不同的对象),但不能修改它所指向的值(即wPtr指针),也不能修改wPtr指向的值。这并没有提供修改const左值的(普通)途径。
当然,第一个例子显然是危险的,也是不允许的,就像你所预期的那样。
顺便说一句,如果你还没有阅读过C++ FAQ中的“const正确性”章节,你应该阅读一下。第17节详细介绍了这个特定情况,虽然主要从为什么不允许第一个角度出发,并没有明确地尝试描述为什么允许第二个。

1
谢谢,你的回答和C++ FAQ链接解决了我的问题。我之前从错误的角度看待了这个问题。 - regu

0

因此,在一个单词左边放置'const'这个词是相当具有误导性的。

您的第二个语句最好陈述为double const * *wRef = &wPtr
基本上,这是指向指向常量double的指针。您可以在此处修改lvalue,因为它不是常量 - 只有指向的double是常量。

第二个是double const * const * wRef - 即指向常量指针的常量指针。
指向指针本身可以更改,但然后它指向的double必须是常量。 您不能修改常量lvalue。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接