为什么有些人比“const T&”更喜欢“T const”?

所以,我意识到const T&T const&是相同的,都是指const T的引用。在这两种情况下,引用也是常量(引用不能像指针那样被重新赋值)。 我观察到,在我有限的经验中,大多数C ++程序员使用const T& ,但是我遇到了一些使用T const& 。 我使用const T&只是因为我是这样学习的,所以T const&对我来说看起来有点儿滑稽。 您使用您使用的变体的原因是什么? 你们中的任何一个人是否在编码标准要求使用一种变体的组织中工作?

编辑
根据这些答案,看起来两者之间select的一个原因是你想要像编译器(从右到左)还是像英语(从左到右)那样阅读它。 如果像编译器那样读取它,那么“T const&”读作“&(引用)const(对于常量)T(typesT)”。 如果从左到右读一个英文的话,那么“const T&”被读作“一个引用forms的T类常量对象”。 我喜欢像英文散文一样阅读它,但我当然可以看到编译器的解释方式。

没有人回答这个组织或者编码标准问题,但是我强烈怀疑大多数组织并没有强制要求,尽pipe他们可能会争取一致。

我想有些人只是喜欢从右到左阅读声明。 const适用于左手标记,除非在那里没有任何东西,它适用于右手标记。 因此, const T&涉及到“除了”的条款,也许可以被认为更复杂(实际上两者应该是容易理解的)。

比较:

 const T* p; (pointer to T that is const) T const* p; (pointer to const T) //<- arguable more natural to read T* const p; (const pointer to T) 

当你有一个const / volatile修饰符时,这会有所作为。 然后把它放在types的左边仍然有效,但是会打破整个声明的一致性。 例如:

 T const * const *p; 

意味着p是一个指向const T的const指针的指针,并且你一直从右向左阅读。

 const T * const *p; 

意味着相同但一致性丢失,你必须记住,最左边的const / volatile是绑定到T而不是T *。

如果你觉得这个讨论很有趣,你可能会发现Dan Saks的这篇文章很有趣。 它不直接解决你的问题,但解释他为什么喜欢

 VP const foo[]; 

 const VP foo[]; 

这是因为给予

 typedef void *VP; 

你很容易被误解为认为上面的第二个例子的意思

 const void *foo[]; // Wrong, actually: void *const foo[]; 

但第一个例子很难曲解。

我觉得是个人喜好。 两个变体之间没有区别。

由于代码主要是基于英文的,所以程序员倾向于从左到右阅读,所以const T&自然而然地向我们读取编译器从右向左读取它的内容,所以T const&自然读取(引用const T)

我的推理如下:

如果你写下“const T”,它似乎更好地滚动舌头,但是当你这样做的时候,最终会出现模糊的“常量T参考”。 我已经看到这个问题不止一次地出现在代码的可理解性上,即使是半经验的人也会错误地理解什么是什么意思或者如何声明更复杂的types。

我现在想不出任何例子,但不止一次,我已经回答了关于types声明和常量问题是由于使用“const T&”而不是“T const&”的习惯导致的问题。 我以前也是这样写的,当我成为高级开发人员时,负责指导和创build项目代码标准的人员,当我强迫每个人使用“T const”时,我发现入门级开发人员更容易。 我想一个相当微不足道的菜鸟错误是为什么这个代码会编译?

 const T* t = f(); t = 0; // assignment to const?? - no, it is not the T* that is const, just the T. 

当你学会按照编译器的方式来阅读它时,就会更容易理解任何给定的复杂types,以及在需要时可以更容易地声明复杂types。 通过复杂的types我正在谈论的事情,如:

T const * const&

当你知道编译器从右到左读,从里到外,这意味着什么是非常明显的,当有必要写一个你可以很容易地做到这一点:引用常量指针常量T.现在写一个声明“引用指向T的常量指针的指针”。 如果你只是使用从左到右的符号,我想你会发现这很容易。

简而言之,虽然最初看起来不自然地使用右边的语法,而不是只在需要的时候才使用右边的语法(因为经常是这样),你会发现记住一行代码意味着多么容易以及如何写你的意思。 这与我为什么在声明中不允许“,”的相同之处在于:

 T* ptr1 = 0, ptr2 = 0; // oops!!! 

T* ptr1 = 0, ptr2 = 0; // oops!!!

//请这样做!
T * ptr1 = 0;
T * ptr2 = 0;

从技术上讲,这一切都是一样的,但是当你试图让一群不同能力的人在同一件事上工作时,你会倾向于确保每个人都使用最简单易懂的方法。 我的经验告诉我,“T const”就是这个方法。

这是因为有些人发现从右向左读取声明是有帮助的。

 char const* const char* 

都是指向const char的指针。