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.