2016-07-23 13 views
34

Yeni bir özel proje başlattım ve bu sefer daha fazla C++11/14 kullanmaya karar verdim. Bu yüzden de çok iyi çoğunlukla çalışır yeni dönüş sözdizimiYeni C++ return sözdizimi sınırlı mı?

auto functionName() -> returnType; 

kullanmaya başladı, ama şimdi bazı hata işleme gerekli ve bunun gibi yeniden yazma nasıl şeyler dışarı bulamadık:

virtual const char* what() const noexcept override; 
Yeni sözdizimi ile

. Yeni sözdiziminin kullanılamadığı bazı durumlar var mı yoksa sadece doğru düzeni bulmak için yeterince akıllı değil miyim? Benim için işleri tutarlı tutmak önemlidir, umarım sorun benim tarafımda daha fazladır.

+0

burada bakın noexcept için: http://stackoverflow.com/questions/16598320/trailing-return-type-syntax-fails-with-noexcept-specifier –

+14

yeni döndürme türü şey gerçekten kesmek izin edilir Fonksiyon parametrelerinde decltype() kullanımı. Fonksiyon parametrelerinin sadece decltype _after_'de kullanılabildiğinden, bu tür bir yapı geri dönüş tipi için 'eski' noktaya yerleştirilemez - bu nedenle dönüş türünü etrafa taşıdılar. Benim düşünceme göre, derleyici yazarlarına, tüm dili herkes için daha az faydalı hale getirme pahasına çok fazla yardımcı oluyor. Her halükarda, tüm projeleri “yeni” söz dizimine dönüştürmeniz için hiçbir ideolojik sebep yoktur; doğal olarak daha iyi veya daha modern değildir. –

+4

Daha güzel göründüğü sürece, jenerik olmayan koddaki son dönüş tipi sözdizimini kullanmak için herhangi bir neden bilmiyorum. Tüm "modern" kodlarda varsayılan olarak "varsayılan" olarak kullanılması amaçlanan "auto" veya brace initialization gibi bazı C++ 11 özellikleri vardır, ancak emin adımların yalnızca belirli bir alt kümesini desteklemek için var Daha önce yazmak mümkün olmayan türafe genel kod. – Ixrec

cevap

34

Evet, normalde tahmin edeceğiniz bir şey değil.

virtual auto what() const noexcept -> const char * override; 

Bu yalnızca kullanmak zorunda olduğunuz sıranız. Sözdizimi muhtemelen farklı olabilirdi, ama sahip olduğumuz şey bu.

+13

Ugh. Ve neden kimse bunun daha üstün olduğunu düşünüyor? Kesinlikle daha okunabilir değil. Bu gösterim, gerçekten gerekli olduğu şablonlarda olduğu gibi sınırlı durumlarda kullanılmalıdır. –

+1

Söz dizimi neden farklıydı? Yeni sözdizimi, * döndürme türü *, niteleyiciler veya başka şeyler değil, geciktirir ... "sanal", "const", "geçersiz kıl" ve "noexcept" geri dönüş türünün parçası değildir, böylece bulundukları yerde kalırlar. – gigabytes

+5

@CodyGray Hiç kimse yeni sözdiziminin burada daha temiz olduğunu söylemezdi. Bu durumda kullanmamanızı tavsiye ederim. Geri dönüş türünü oluşturmak için kapsamdaki tür işlev parametrelerine sahip olmanız gereken genel kod için tanıtıldı. Estetik bir sebep değil. Ah, ve lambdas için, elbette ... – gigabytes

21

Yeni sözdizimi, eski söz diziminin yaptığı her şeyi desteklemektedir.

virtual const char* what() const noexcept override; 


Aslında yeni sözdizimi bile daha fazla özellik destekler

virtual auto what() const noexcept -> const char * override; 

olarak yeniden yazılması gerekir: Bu fonksiyon argümanları üzerinde decltype yapmanızı sağlar

  • .

    template <typename A, typename B> auto plus(A a, B b) -> decltype(a+b) 
    { 
        return A + B; 
    } 
    
  • Ayrıca sırayla size üye fonksiyonları üzerindeki decltype yapmak olanak veren this üzerinde decltype yapmanızı sağlar. See this.


struct S 
{ 
    int a() {return 1;} 
    auto b() -> decltype(a()) {return 2;} // Works. 
    decltype(a()) c() {return 2;} // ERROR. 
}; 
Ancak yeni sözdizimi tüm bu ek özelliklere sahipken, eski biri için bir yedek olmak zorunda değil. En azından bunu nasıl anladım.

Bazı programcılar kullanmayı tercih eder, ancak buradaki çoğu programlayıcıyı bildiğim kadarıyla Stack   Overflow, mümkün olduğunda eski sözdizimini kullanmayı tercih eder.

+5

Ve özellikle sondaki dönüş tipi, sınıfında tanımlanmış bir tür kullanmanıza izin verir, dönüş türünde niteliksiz. –

36

sorun nedeni noexcept fonksiyonu Bildiricisi bir parçasıdır (ve işlevinin bir parçası C++ 17 yazın olması önerilmektedir) override bir parçası olmayan bir (isteğe bağlı olarak kullanılan) tanımlayıcısı iken, yani işlev belirleyicisi.

Bu nedenle, override kullanılmadan beyan override bu beyan sonra ortaya gerekir, çünkü tıpa tıp C kullanarak yerine, söz konusu bu

virtual auto what() const noexcept -> const char * override; 

neden olur,

virtual auto what() const noexcept -> const char *; 

olacağını ve ++ 11/C++ 14 özellikleri, amacınızı en iyi yansıtan özellikleri seçin. Aynı şeyi elde etmek için daha eski alternatifler varsa, yalnızca C++ 11/C++ 14 özelliklerinin kullanılmasını gerektiren bir kural yoktur.

0

Senaryo için C++ 14'ü de sorduğun için, bu, sonek tipi yazım sözdiziminden daha iyi;

virtual auto what() const noexcept override; 
+1

... geri dönüş türünü tamamen çıkarmanıza izin verilen durumlarda (örneğin, birden çok 'return' deyiminiz olduğunda yasa dışı olabilir) –