const int *p 与 int const *p - 类型后面的 const 是否可以接受?
我的同事对他启发的问题的得分是 0 比 2 (1< /a>,2),所以我想我应该给他一个机会跟上来。
我们最新的分歧是关于在声明中放置“const
”的样式问题。
他认为它应该位于类型前面或指针后面。 原因是,这通常是其他人所做的,而其他风格很容易令人困惑。 因此,指向常量 int
的指针和指向 int
的常量指针将分别是:
const int *i;
int * const i;
但是,我还是很困惑。 我需要一致且易于理解的规则,而我理解“const
”的唯一方法是它位于它正在修改的内容之后。 有一个例外允许它位于最终类型之前,但那是一个例外,所以如果我不使用它,对我来说会更容易。
因此,指向常量 int
的指针和指向 int
的常量指针分别是:
int const * i;
int * const i;
作为一个额外的好处,以这种方式执行操作可以使更深层次的间接更容易理解。 例如,指向 int
的常量指针的指针显然是:
int * const * i;
我的论点是,如果有人按照自己的方式学习它,他们将很容易弄清楚上面的结果。
这里的最终问题是,他认为将 const
放在 int
后面是难以形容的丑陋,并且对可读性非常有害,因此应该在样式指南中禁止它。 当然,我认为指南应该建议按照我的方式进行,但无论哪种方式,我们都不应该禁止一种方法。
编辑: 我得到了很多好的答案,但没有一个真正直接解决我的最后一段(“最终问题”)。 很多人都主张一致性,但在这种情况下,这是否如此理想,以至于最好禁止其他实现方式,而不是仅仅阻止它?
My co-worker is 0 for 2 on questions he has inspired (1, 2), so I thought I'd give him a chance to catch up.
Our latest disagreement is over the style issue of where to put "const
" on declarations.
He is of the opinion that it should go either in front of the type, or after the pointer. The reasoning is that this is what is typically done by everyone else, and other styles are liable to be confusing. Thus a pointer to a constant int
, and a constant pointer to int
would be respectively:
const int *i;
int * const i;
However, I'm confused anyway. I need rules that are consistent and easy to understand, and the only way I can make sense of "const
" is that it goes after the thing it is modifying. There's an exception that allows it to go in front of the final type, but that's an exception, so it's easier on me if I don't use it.
Thus a pointer to a constant int
, and a constant pointer to int
would be respectively:
int const * i;
int * const i;
As an added benefit, doing things this way makes deeper levels of indirection easier to understand. For example, a pointer to a constant pointer to int
would clearly be:
int * const * i;
My contention is that if someone just learns it his way, they'll have little trouble figuring out what the above works out to.
The ultimate issue here is that he thinks that putting const
after int
is so unspeakably ugly, and so harmful to readability that it should be banned in the style guide. Of course, I think if anything the guide should suggest doing it my way, but either way we shouldn't be banning one approach.
Edit:
I've gotten a lot of good answers, but none really directly address my last paragraph ("The ultimate issue"). A lot of people argue for consistency, but is that so desirable in this case that it is a good idea to ban the other way of doing it, rather that just discouraging it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
最重要的是一致性。 如果没有任何编码指南,那么选择一个并坚持使用。 但是,如果您的团队已经有了事实上的标准,请不要更改它!
也就是说,我认为到目前为止更常见的是
因为大多数人都写
而不是
旁注 - 读取指针常量的一种简单方法是从右侧开始读取声明。
The most important thing is consistency. If there aren't any coding guidelines for this, then pick one and stick with it. But, if your team already has a de facto standard, don't change it!
That said, I think by far the more common is
because most people write
instead of
A side note -- an easy way to read pointer
const
ness is to read the declaration starting at the right.有一类示例将 const 放在类型右侧也有助于避免混淆。
如果 typedef 中有指针类型,则无法将类型的常量更改为:
pi
仍然具有类型int * const< /code>,无论你在哪里编写
const
,这都是一样的。There's a class of examples where putting the
const
on the right of the type also helps avoid confusion.If you have a pointer type in a typedef, then it is not possible to change the constness of the to type:
pi
still has the typeint * const
, and this is the same no matter where you write theconst
.我希望 B. Stroustrup 关于 Style & 的常见问题解答对此做出解释。 技术会给你明确的答案。
Bjarne Stroustrup 的 C++ 风格和技术常见问题解答
我个人更喜欢:
因为
const 标识左侧标记,该标记应为常量。
当你使用这样的东西时,你肯定会保持相同的一致性:
而不是不一致地写:
如果你有一个指向指针的指针等等,会发生什么:
而不是:
I hope this explanation from B. Stroustrup's FAQ on Style & Techniques will give you a definite answer.
Bjarne Stroustrup's C++ Style and Technique FAQ
I personaly prefer:
Because
const
identifies the left token which is intended to be const.And you definitely keep the same consistency when using smth like that:
Instead of writing inconsistently:
And what happens if you have a pointer to pointer and so on:
Instead of:
我参加了一次会议,Bjarne Stroustrup 正在做演讲,他使用了类似
const int* i
的东西。 有人问他为什么用这种风格,他回答(释义):I was at a conference where Bjarne Stroustrup was giving a presentation, and he used something like
const int* i
. Someone asked him why does he use this style and he responded (paraphrasing):人们通常使用 const int* blah ,因为它读起来很好英语。 我不会低估它的用处。
我发现 int* const blah 变体非常罕见,因此向后进行更常见的定义通常没有用处。 一般来说,我不喜欢任何在一般情况下稍微模糊代码的东西,尽管它可能在特殊情况下提供一些名义上的好处。
另请参见“if (1 == a)”。 有些人真的很喜欢编写读起来不像英语的代码。 我不是那些人中的一个。
但实际上,const 背后的规则很简单。 向左看,然后向右看。 如此简单,我认为在风格指南中不值得太多关注。
People typically use
const int* blah
because it reads well as English. I wouldn't underestimate the usefulness of that.I find that the
int* const blah
variation is rare enough that it's not typically useful to make the more common definition backwards. I am, in general, not a fan of anything that even slightly obscures code in the general case, though it might provide some nominal benefit in the exceptional case.See also "if (1 == a)". Some people really enjoy writing code that doesn't read as English. I am not one of those people.
Really, though, the rules behind const are simple. Look to the left, then to the right. So simple that I wouldn't think it's worth much attention in a style guide.
如果只是变量和指向它们的指针可以是 const 或不是 const,那么可能就没有那么重要了。 但请考虑一下:
除了尾随它所引用的函数之外,
const
不可能写在其他任何地方。风格指南越短,开发人员就越有可能遵循它。 可能的最短规则,以及为您提供一致性的唯一规则是:
const
关键字始终尾随 无论它指的是什么。所以,我会为你的同事说 0:3。
关于你的“最终问题”:为了风格指南的缘故,指南是否“劝阻”或“禁止”它公开反对的事物并不重要。 这是一个社会问题,一个政策。 风格指南本身应该尽可能简洁。 冗长的风格指南只会被每个人忽视(除了管理人员寻找应受指责的人),因此只需写“做”或“不做”,并在其他地方(例如在公司政策中)说明您对违反指南的行为同行评审的进行方式)。
If it were only variables and pointers to them that could be
const
or not, it would probably not matter that much. But consider:No way that
const
could be written anywhere else but trailing the function it refers to.The shorter a style guide, the more likely developers will follow it. And the shortest rule possible, and the only rule that will give you consistency, is:
The
const
keyword always trails whatever it is referring to.So, I'd say 0:3 for your coworker here.
Regarding your "ultimate issue": For the sake of the style guide, it does not matter whether the guide "discourages" or "bans" the things it speaks out against. That is a social issue, a policy. The style guide itself should be as crisp and short as possible. Long style guides just get ignored by everybody (except management on the lookout for someone to blame), so just write "do" or "don't", and state what you do with violations of the guide elsewhere (e.g. in the company policy of how peer reviews are being done).
虽然
const int
和int const
之间没有任何有意义的区别(并且我已经看到这两种样式都在使用),但const int *< 之间存在差异/code> 和
int * const
。在第一个中,您有一个指向 const int 的指针。 您可以更改指针,但无法更改它指向的值。 在第二个中,你有一个指向 int 的 const 指针。 您无法更改指针(希望它已根据您的喜好进行初始化),但您可以更改所指向的 int 的值。
正确的比较是与 const int * 和 int const * 进行比较,它们都是指向 const int 的指针。
请记住,
*
不一定按您希望的方式工作。 声明int x, y;
将按照您的预期工作,但int* x, y;
声明一个指向 int 的指针和一个 int。While there is no meaningful difference between
const int
andint const
(and I've seen both styles in use), there is a difference betweenconst int *
andint * const
.In the first, you have a pointer to a const int. You can change the pointer, but you can't change the value it points to. In the second, you have a const pointer to int. You can't change the pointer (hope it's initialized to your liking), but you can change the value of the pointed-to int.
The proper comparison is with
const int *
andint const *
, which both are pointers to a const int.Remember that the
*
doesn't necessarily work as you might like. The declarationint x, y;
will work as you expect, butint* x, y;
declares one pointer to int, and one int.一旦您训练自己从右向左阅读 C++ 类型声明,将“const”放在类型声明之后就变得更有意义。
我要把你的牛人定为 0 换 3 :)
Putting "const" after the type declaration makes a whole lot more sense once you train yourself to read your C++ type declarations from right to left.
I'm going to peg your cow-orker at 0-for-3 :)
就我个人而言(这是个人偏好),我发现从右到左阅读类型声明是最简单的。 尤其是当你开始将参考文献混入其中时。
Personally I (and it is a personal preeference) I finding reading type declarations from right to left the easiest. Especially when you start throwing references into the mix.
真的吗?
向我展示一个在看到以下内容时陷入困境的程序员:
vs
...,我将向你展示一个对细节不够关注的程序员。
任何称职的专业程序员都不会因为风格上的表面差异而烦恼。
编辑:确实 const int* 和 int* const 并不意味着完全相同的事情,但这不是重点。 OP 同事提出的观点是,风格的差异使得代码难以理解和理解。 维持。 我不同意这种说法。
Really?
Show me a programmer who gets bogged down when he sees:
vs
...and I'll show you a programmer who doesn't pay close enough attention to detail.
No professional programmer worth his salt will have a problem with superficial differences in style.
EDIT: It is true that const int* and int* const don't mean exactly the same thing, but that wasn't the point. The point made by OP's coworker was that differences in style make code difficult to understand & maintain. It is this claim I disagree with.
让我把我的 2 美分投入到讨论中。
在现代 C++ 中,我建议坚持使用
int const
而不是const int
以突出const
和constexpr
之间的区别代码>. 这将帮助程序员记住 const int 不能总是被认为是编译时常量,因为:Let me put my 2¢ into the discussion.
In modern C++ I'd recommend to stick to
int const
instead ofconst int
to highlight the difference betweenconst
andconstexpr
. It would help programmer to remember thatconst int
cannot be always thought as compile-time constant, because:constexpr
can.规则是很好遵守的。 规则越简单越好。
Const 位于 const 的右侧。
采取这个声明:
int
主要的
( int 常量 argc
, char const * const * const argv
)
...
Rules are good to follow. Simpler rules are better.
Const goes to the right of what's const.
Take this declaration:
int
main
( int const argc
, char const * const * const argv
)
...
我同意你们俩的观点。 您应该将 cons 放在类型后面。 我还发现看着它是一种必须被摧毁的可憎行为。 但我最近对 常量值参数 的奇迹的尝试让我明白了为什么要把const 第二个有意义。
光是看着就让我脖子上的汗毛都竖起来了。 我确信这会让我的同事感到困惑。
编辑:我只是想知道如何在类中使用它:
此示例中的
bar
在功能上等同于Bar&
但它位于堆上并且可以删除。 在每个 Foo 的生命周期中,都会有一个与其关联的 Bar。I agree with both of you. You should put the const after the type. I also find looking at it an abomination that must be destroyed. But my recent foray into the wonders of const value parameters has made me understand why putting the const second makes sense.
Just looking at that has the hairs on my neck standing. I'm sure it would confuse my co-workers.
EDIT: I was just wondering about using this in classes:
bar
in this example is functionally equivalent toBar&
but it is on the heap and can be deleted. For the lifetime of each Foo, there will be a single Bar associated with it.我喜欢使用以下形式声明“清单常量”。 在本例中,值本身是一个常量,因此我将“const”放在前面(与 Bjarne 相同)以强调这一点常量应该在编译时显现出来,并且可用于编译器的特定优化。
为了声明不会用于修改值的引用,我使用以下形式,强调标识符是“常量引用”这一事实。 参考值可以是也可以不是常数。 [相关讨论:如果函数参数不是指针或引用,您还会使用“const”吗? 使用“const”作为函数参数]
对于指针,我使用相同的我用于引用的形式,本质上是出于相同的原因(尽管术语“常量指针”似乎比“常量引用”更加模糊)。
此外,正如另一位发帖者指出的那样,当您具有多个间接级别时,这种形式保持一致。
最后一种情况,即声明一个常量指针,在我的 C++ 经验中很少见。 无论如何,你在这里真的没有任何选择。 [此案例表明,最一致的方法是将单词“const”放在类型之后 - 因为事实上,这是此特定声明的必需。 ]
...除非你使用 typedef。
最后一点:除非您在低级域中工作,否则大多数 C++ 代码应该永远不要声明指针。 因此,这个讨论的这个方面可能与 C 更相关。
I like to to use the following form for declaring "manifest constants". In this case, the value itself is a constant so I put the "const" first (same as Bjarne) to emphasize that the constness should be manifest at compile-time, and usable as such for specific optimizations by the compiler.
For declaring references which will not be used to modify the value, I use the following form which emphasizes the fact that the identifier is a "constant reference". The referenced value may or may not be a constant. [Related discussion: Would you even be using "const" for function parameters if they were not pointers or references? Use of 'const' for function parameters]
For pointers, I use the same form that I use for references, for essentially the same reason (although the term "constant pointer" seems a little more ambiguous than "constant reference").
Also, as another poster noted, this form remains consistent when you have multiple levels of indirection.
The final scenario, where you are declaring a pointer which is constant is pretty rare in my experience with C++. In any case, you don't really have any choices here. [This case demonstrates that the most consistent approach would be to put the word "const" after the type -- since that is, in fact, required for this particular declaration.]
...unless you use a typedef.
One final note: Unless you are working in a low-level domain, most C++ code should never declare a pointer. Therefore, that aspect of this discussion is probably more relevant to C.
在现代 C++11 中,您还可以使用模板 typedef 来增加复杂声明的清晰度:
您在问题中提到的三个声明:
然后将写为:
In modern C++11, you could also use template typedefs to add clarity to complicated declarations:
The three declarations you mentioned in your question:
would then be written as: