işlev başlığında ok operatörü (->)


129

Aşağıdaki kodla karşılaştım:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

Anlayamadığım bir şey var:

Ok operatörünün ( ->) işlev başlığında ne anlama geldiğini nereden öğrenebilirim ? Sanırım tamamen mantıksal olarak, ->operatörün autoçıkarılacak bir türü belirlediğini , ancak bunu açıklığa kavuşturmak istiyorum. Herhangi bir bilgi bulamıyorum.


2
Sondaki dönüş türü sözdiziminin bir parçasıdır. Bkz. Stackoverflow.com/a/4113390/962089
chris

2
Bir operatör değil, sözdiziminin bir parçasıdır.
texasbruce

1
"Nerede okuyabilirim?" Sorusuna yanıt olarak, C ++ Spesifikasyonu en güvenilir olanıdır. Fon eksikliği veya $$ harcama isteği nedeniyle, son çalışan taslak genellikle yeterince yakındır ve maliyetsizdir. Bu özellikler oldukça tekniktir, bu nedenle ISO spesifikasyonlarını okumaya aşinalık eksikliği nedeniyle cplusplus.com veya cppreference.com veya yetkili olmayan ancak genellikle çok doğru olan bu tür diğer siteleri deneyin. Not: Sondaki dönüş türü C ++ 14'ten başlayarak ihmal edilebilir.
Les

Yanıtlar:


206

C ++ 11'de, işlev bildirimi için iki sözdizimi vardır:

    dönüş tipi tanımlayıcı ( argüman beyanları ... )

ve

    auto tanımlayıcı ( bağımsız değişken-bildirimler ... ) -> dönüş_türü

Bunlar eşdeğerdir. Şimdi eşdeğer olduklarında, neden ikincisini kullanmak istiyorsunuz? C ++ 11 decltype, bir ifadenin türünü tanımlamanıza izin veren bu harika şeyi tanıttı . Dolayısıyla, dönüş türünü bağımsız değişken türlerinden türetmek isteyebilirsiniz. Yani dene:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);

ve derleyici bu ne bilmiyor söyleyecektir ave biçindedir decltypeargüman. Bunun nedeni, yalnızca argüman listesi tarafından bildirilmeleridir.

Daha declvalönce bildirilmiş olan şablon parametrelerini kullanarak sorunu kolayca çözebilirsiniz . Sevmek:

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);

şu anda gerçekten ayrıntılı hale gelmesi dışında. Böylece alternatif bildirim sözdizimi önerildi ve uygulandı ve şimdi yazabilirsiniz

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);

ve daha az ayrıntılı ve kapsam kurallarının değişmesi gerekmiyordu.


C ++ 14 güncellemesi: C ++ 14 ayrıca yalnızca

    auto tanımlayıcı ( argüman beyanları ... )

işlev kullanımdan önce tam olarak tanımlandığı ve tüm returnifadeler aynı tipte olduğu sürece . ->Eğer kaynak dosyada vücudu gizlemek istiyorsanız sözdizimi (başlığında bildirilmiş) Kamu fonksiyonlar için faydalıdır kalır. Açıkça bu, şablonlarla yapılamaz, ancak başka türlü yazılması zor olan bazı somut türler (genellikle şablon meta programlaması yoluyla türetilir) vardır.


2
çok iyi, temiz ve bilgilendirici yanıt @ Jan Hudec. Vuruyor. Değişti orada şey mi C++14ben kullandıkça autoiçin returngerek kalmadan bu tür fonksiyonunda tip -> decltype(a + b)parçası. Şimdiye kadar gereksiz mi yoksa hala kullanılması gereken başka durumlar var mı? veya derleyiciye özel bir uzantı mı?
Shadi

1
@Shadi, C ++ 14 , işlev kullanımdan önce tam olarak tanımlandığı ve tüm ifadeler aynı türden çıkarıldığı sürece gösterim autoolmadan olarak bildirilen dönüş türünün çıkarılmasına izin veren N3638'i içerir . Eğer kaynak dosyada vurmada ise kamu fonksiyonu için kesinti kullanmak istiyorsanız notasyonu yine de yararlıdır. ->return->
Jan Hudec

24

Düz ingilizce, geri dönüş tipi toplamının çıkarımlara türü olduğunu söyler ave b.

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.