std::is_const将const指针识别为非const

7

我对std::is_const在将一个const指针识别为非const时的行为感到困惑。我的is_const实现也完全一样。我不确定为什么更通用的模板结构<T>被选择而不是<const T>版本。gcc4.7和clang3.1-svn都显示相同的行为。有人能解释一下发生了什么吗?以下是代码:

#include <iostream>
#include <sstream>
#include <type_traits>

class CEmptyClass {}; 

namespace jbc 
{
  template <typename T>
  struct is_const : std::false_type {}; 

  template <typename T>
  struct is_const<const T> : std::true_type {}; 
}

int main(int argc, char* argv[])
{
  std::cout << "Is 'const CEmptyClass*' constant according to std lib : " 
    << std::is_const<const CEmptyClass*>::value << std::endl;
  std::cout << "Is 'const CEmptyClass*' constant according to jbc : " 
    << jbc::is_const<const CEmptyClass*>::value << std::endl;
}

在这两种情况下,is_const<const CEmptyClass*>::value 均返回0

3
我对std::is_const在将一个const指针识别为非const时的行为感到困惑。代码中没有const指针,只有指向const的非const指针 - David Rodríguez - dribeas
您是正确的。我一直将指向常量的指针看作是常量,但实际上并不是这样。 - jbcoe
1个回答

19

不存在所谓的const引用,引用永远不会是const。像这样的代码无法编译:

int& const i;

如果你删除掉引用,代码就可以正常工作。如果你将const放在右边(从语义上来说是相同的),并将类型倒过来读取。

现在如果您删除引用,则会正常工作。 如果将const放在右侧(在语义上是相同的),并将类型向后读取。

CEmptyClass const&

它将会读取一个指向constCEmptyClass引用,而不是一个指向CEmptyClassconst引用

更新: 现在你把引用改为了指针,但同样的错误仍然存在:

const CEmptyClass*
CEmptyClass const*

两者是相同的,一个指向常量CEmptyClass的非const指针

CEmptyClass* const

是指一个指向CEmptyClass的常量指针

以及

const CEmptyClass* const
CEmptyClass const* const

是指一个指向常量CEmptyClass的const指针。


真的。将引用更改为指针(问题和代码已更新),仍然保留了神秘的行为。为什么const T*不是const - jbcoe
2
@j 代码:const T*T const* 是相同的,它们都是指向 const T 的 _指针_,再次强调不是 const。同时,T* constconst T* constT const* const 才是 const - K-ballo
1
“并且将类型倒过来读” - 天才啊,终于有一种方法可以读这些复合声明了... - Phil H

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