C ++: const başvurusu, type belirtecinden önce vs sonra


145

Aşağıdaki argümanlar arasındaki fark nedir:

int foo1(const Fred &arg) {
...
}

ve

int foo2(Fred const &arg) {
...
}

? Bu davanın parashift SSS'de kapandığını görmüyorum.



2
bu stil hakkında bir soru mu? "const Fred" İngilizce iyi geliyor, ama "Fred const" bana daha iyi görünüyor.
LatinSuD

1
İlgili bir tek tercih için bir neden yoktur Fred const &argüzerinde Fred const& arg? Ben ikincisini daha çok seviyorum çünkü const&orada "constref" anlamına gelen bir birim ve isim argtüm tip belirteçlerinden bir boşluk ile ayrılmıştır.
Frank

4
@dehmann: Ama int const& ref'const ref' değil, 'const' ref demek değildir.
Cedric H.

Yanıtlar:


113

Const olarak hiçbir fark & ile ilgili olarak sağdan sola okunmaz, bu nedenle her ikisi de değişmez bir Fred örneğine bir referansı temsil eder.

Fred& constolduğu kendisi değişmez referans, anlamına gelir gereksiz ; ile uğraşırken const işaretçiler hem Fred const*ve Fred* constgeçerli ama farklıdır.

Bu bir stil meselesidir, ancak const üye işlevlericonst de dahil olmak üzere tutarlı bir şekilde uygulanabileceğinden bir sonek olarak kullanmayı tercih ederim .


Öyleyse dikkat edilmesi std::is_const<const T&>::valuegereken nokta falsenedir?
Abyss.7

@ abyss.7 bu bir referanstır const T; referans değiştirilebilir.
Sean Fausett

125

davranış

const T&Ve arasında anlamsal bir fark yoktur T const&; dil onlara aynı tür davranır. (Aynı şey const T*ve için de geçerlidir T const*.)

Bir stil meselesi olarak

Bununla birlikte, stilistik olarak hangisini tercih etmeniz gerektiğiyle ilgili olarak, diğer birçok cevaptan muhalif olacağım ve tercih edeceğim const T&(ve const T*):

  • const T&Stroustrup'un C ++ Programlama Dili kitabında kullanılan stildir .
  • const T& C ++ standardının kendisinde kullanılan stildir.
  • const T*K & R'nin C Programlama Dili kitabında kullanılan stildir .
  • const T* C standardında kullanılan stildir.
  • Yukarıdaki nedeniyle faktörlere, sanırım const T&/ const T*çok daha fazla atalete sahip olan T const&/ ' T const*. const T&/ const T*empirik olarak gördüğüm tüm C ++ ve C kodundan daha yaygın T const&/ bana göre daha yaygın görünüyor T const*. Ortak uygulamaları takip etmek, sağdan sola ayrıştırma kurallarına dogmatik olarak uymaktan daha okunabilir.
  • İle T const*o yanlış yere daha kolay görünüyor, *olarak T* const(insanlar olarak buna alışkın değil, özellikle). Buna karşılık, const* Tyasal sözdizimi değildir.

Sağdan sola ayrıştırma kuralı ne olacak?

İnsanların kullanmayı sevdiği tüm sağdan sola ayrıştırma argümanıyla ilgili olarak: başka bir cevaba yapılan bir yorumda belirttiğim gibi, const T&sağdan sola da iyi okur. Bu bir T sabiti referansıdır. "T" ve "sabit" her biri sıfat veya isim olarak çalışabilir. (Buna ek olarak, okuma T const*sağdan sola yanlış "işaretçi sabit olarak yorumlanabilir çünkü belirsiz olabilir için yerine" işaretçi olarak T " ile sabit bir T").


3
+1, kabul etti. Kodu okurken, çizgi const ile başlarsa bir sabitin tespit edilmesi daha kolaydır. Sağ-sol kuralı gerçekten sadece özellikle kıllı tip bildirimleri ayrıştırırken gereklidir. Neden en yaygın durum için optimizasyon yapmıyorsunuz? Ayrıca, IMHO tip bildirimleri yazarsanız, kafanızda bir FSM'yi manuel olarak çalıştırmanız gerekir.
Andreas Magnusson

2
-1. Sonuçlarınızın ne kadar haklı olduğuna ve ne kadar kişisel olarak kabul ettiğime bakılmaksızın , sorulan soruyu doğrudan cevaplamıyorlar . Bu, basit bir soruya verilen en ikinci ikinci cevabı, dağınık sualtı makineleri hakkında konu dışı anlamsız gibi görünüyor, sonuç yok, doğrudan cevap yok - hiçbir şey. " Hayır, her iki sözdizimi arasında anlamsal bir fark yok , ancak aşağıdaki gibi bazı stilistik düşünceler var ..." diyen basit bir özet eklediğinizde benim oyumu alacaksınız . Ve ancak o zaman tüm mermiler.
ulidtko

1
IMO'nun nedeni const T&daha iyi okunuyor: 1- Kodu soldan sağa okuyoruz. 2- Yeni bir kavramı tanımlarken daha genel kavramdan daha spesifik olana başlarız. Burada constanahtar kelime, değişken alanı iki kategoriye ayırdığı için daha geneldir, oysa tür belirleyici bunu birçok kategoriye ayırır.
pooya13

"pointer to" birlikte kalmalıdır. Yani bir belirsizlik yokT const*
Dexter

13

Bir ve aynı olmalarına rağmen, C ve C ++ bildirimlerini ayrıştırma konusunda SAĞ-SOL kuralla tutarlılığı korumak için, yazmak daha iyidirFred const &arg

Ayrıca bildirimler, niteleyiciler ve bildiriciler hakkında daha fazla anlayış geliştirmek için bunu belirtin.


1
Soneki tercih ederim, çünkü typedefgenişleme ile daha iyi çalışır . Örnek: typedef int* pointer;, const pointer değil const int* , bu kadar int* const. Son ek formu garip değil.
Matthieu M.12

4
IMO da const T&sağdan sola iyi okuyor; bir T sabiti referansıdır. Tve constanther biri sıfat veya isim olarak çalışabilir.
jamesdlin

7

Her ikisi de işe yarar ve işte onu yazan adamın açıklaması.
Ona alıntı yapmak için:

Neden? "Const" i icat ettiğimde (başlangıçta "salt okunur" olarak adlandırılıp karşılık gelen bir "writeonly" a sahip olduğumda, belirsizlik olmadan yapabileceğim için türden önce veya sonra gitmesine izin verdim.




3

Referanslar işaretçilerle aynı şekilde çalışmaz: işaretçiler için 'sabit işaretçiler' ( type * const p) ve 'sabitlemek için işaretçiler' ( const type * pveya type const * p) kullanabilirsiniz.

Ancak referanslar için buna sahip değilsiniz: bir referans her zaman aynı nesneyi ifade eder; bu anlamda 'referansların' 'const referansları' olduğunu düşünebilirsiniz ('const işaretçileri' olabilir gibi).

Bu nedenle 'type & const ref' gibi bir şey yasal değildir. Yalnızca 'tipe referans' ( type &ref) ve 'sabit türe referans' ( const type &refya da type const &refher ikisi de tam olarak eşdeğerdir) olabilir.

Son bir şey: const typeİngilizce'de daha doğru görünse bile , yazma type const"sağdan sola" bildirimlerinin daha sistematik bir şekilde anlaşılmasını sağlar: int const & refokunabilir 'ref sabit int'e bir referanstır'. Ya da daha karmaşık bir örnek: int const * const & refref, sabit int'e sabit bir göstergeye yapılan göndermedir.

Sonuç: sorunuzda her ikisi de tam olarak eşdeğerdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.