typedef 和 const 指针的容器
以下代码行可以正常编译并运行:
list<const int *> int_pointers; // (1)
以下两行则不然:
typedef int * IntPtr;
list<const IntPtr> int_pointers; // (2)
我得到完全相同的编译错误,因为
list<int * const> int_pointers; // (3)
我很清楚最后一行不合法,因为 STL 容器的元素需要可分配。为什么编译器将 (2) 解释为与 (3) 相同?
The following line of code compiles just fine and behaves:
list<const int *> int_pointers; // (1)
The following two lines do not:
typedef int * IntPtr;
list<const IntPtr> int_pointers; // (2)
I get the exact same compile errors for
list<int * const> int_pointers; // (3)
I'm well aware that the last line is not legal since the elements of an STL container need to be assignable. Why is the compiler interpreting (2) to be the same as (3) ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
简短回答:
(和 volatile)自然应该出现在它们限定的类型之后。
当你之前编写它时,编译器会自动在内部重写它:
成为
指向常量int的指针。这些列表可以很好地编译,因为指针本身仍然是可分配的。
Short answer:
const (and volatile) should naturally appear after the type they qualify.
When you write it before, the compiler automatically rewrites it internally:
becomes
which is a pointer to a constant int. Lists of these will compile fine since the pointer itself is still assignable.
您可以从右到左阅读 C 风格的类型声明。所以“const int *”是一个指向常量int的指针(“const int”和“int const”的意思是一样的)。这些是完全可以分配的。但 (2) 和 (3) 是指向 int 的常量指针,因此不可赋值。
You read C-style type declarations right to left. So "const int *" is a pointer to constant ints ("const int" and "int const" mean the same thing). Those are perfectly assignable. But (2) and (3) are constant pointers to int, and therefore not assignable.
您问“为什么编译器将 (2) 解释为与 (3) 相同?”。嗯,因为在 C++ 语言(以及 C)中,它们在语义上是相同的。当您稍后定义类型名称时,
类型
const IntPtr
将代表int *const
,而不是const int *
。这就是 typedef-names 在 C++ 中的工作原理。C++ 中的 Typedef 名称不是宏。虽然它们没有定义新类型(只是现有类型的别名),但生成的别名仍然是“原子的”、“整体的”,在某种意义上,应用于别名的任何限定符都将作为顶级应用。 > 预选赛。当您使用 typedef-name 时,无法“潜入” const 限定符,以便它以某种方式“下降”到类型的较低级别部分(在您的情况下为
int
)。如果您坚持使用 typedef 名称,那么您没有其他直接选择,只能提供两个不同的 typedef 名称,例如
当您需要该类型的指向 const 版本的指针时使用
ConstIntPtr
。You are asking "Why is the compiler interpreting (2) to be the same as (3)?". Well, because in C++ language (as well as in C) they are semantically the same. When you define a typename as
then later the type
const IntPtr
will stand forint *const
, not forconst int *
. That's just how typedef-names work in C++.Typedef-names in C++ are not macros. While they do not define new types (just aliases for the existing ones), the resulting aliases are nevertheless "atomic", "monolithic" in a sense that any qualifiers applied to the alias will apply as top-level qualifiers. When you are working with a typedef-name, there's no way to "sneak in" a const qualifier so that it would somehow "descend" to a lower-level portion of the type (
int
in your case).If you insist on using typedef-names, you have no other immediate choice but to provide two different typedef-names, like
and use
ConstIntPtr
when you need a pointer-to-const version of the type.const IntPtr
和const int*
不是一回事。1)
const int*
是“指向const int
的指针”。2)
const IntPtr
扩展为int * const
(想想(int *) const
),即“const
指针到int
”。简而言之,
typedef
的作用就像一组括号。您无法更改typedef
指针所指向内容的const
性质。const IntPtr
andconst int*
are not the same thing.1)
const int*
is "pointer toconst int
".2)
const IntPtr
expands toint * const
(think(int *) const
) which is "const
pointer toint
".In short, the
typedef
is acting like a set of parentheses. You can't change theconst
-ness of what atypedef
'd pointer points to.const int *
和写int const *
一样,表示非常量指针指向的常量值。使用 typedef,您可以将指针本身定义为常量,就像在第三条语句中一样。
const int *
is the same as writingint const *
, meaning a constant value pointed by a non constant pointer.With the typedef you define the pointer itself as constant, like in your 3rd statement.
我确信您知道
const IntPtr
和IntPtr const
是相同的类型。这意味着
list
和list
是相同的类型。这意味着您正在尝试编译此内容:
I am sure you know that
const IntPtr
andIntPtr const
are the same type.Which means
list<const IntPtr>
andlist<IntPtr const>
are the same type.Which means you are trying to compile this: