Haftalık C++ 46 – constexpr fonksiyonlar ve fonskiyonlar için dönüş tipi çıkarımı

Merhaba sevgili yazılımperver dostlarım,

C++ 14 yazılarımıza devam ediyoruz. Bu yazımda, mevcut kabiliyetlere yapılan bir takım ekleme mahiyetindeki özelliğe göz atıyor olacağız. Her ne kadar, çok sık kullanacağınız ya da muhakkak ihtiyacınız olacak kabiliyetler olmasa da, yine de faydalı olacağına inanıyorum. O zaman daha fazla oyalanmadan bunlara bir göz atalım.

constexpr fonksiyonlara ilişkin güncellemeler

constexpr fonksiyonlara ilişkin güncellemelere değinmeden önce elbette C++ 11 ile sunulan kabiliyetlere bakmakta fayda var. Daha detaylı bir hatırlama için aşağıdaki yazıma göz atabilirsiniz. Bu yazım içerisinde constexpr fonksiyonlar yanında, diğer tanımlamalara ve kısıtlara değinmiştim.

Modern C++ (3): Uniform Initialization, override/final, default/delete, constexpr, vb.

Özetleyecek olursak. constexpr fonksiyonlar bize derleme zamanında koşturulabilen ve hesaplamaları da derleme zamanında yapmanıza olanak sağlayan bir mekanizma sunmaktadır.

Peki, bu kabiliyete ilişkin C++ 11’deki kısıtlar neydi? Bir kere virtual olamaz, muhakak argüman içermeli, dönüş değeri, constexpr tanımlamalar ile kullanılabilen “literal type” olmalıdır. Tek bir dönüş ifadesi olmalıdır. Koşul ya da döngü ifadeleri de içeremez (koşul (“Ternary”) operatörü ile koşul kısmını halledebiliyorduk gerçi ama peki şık olmayabilirdi).

Hemen bir örneğe göz atalım isterseniz:

Yukarıdaki örnekte verilen fonksiyon ile çarpma işlemlerini derleme zamanında yapabiliyoruz. Gelelim C++ 14’e.

C++ 14 ile birlikte artık aşağıdakileri de yapabiliyoruz:

  • Fonksiyon içerisinde statik ve ilklendirilmemiş değişkenler dışında, değişken tanımlama,
  • if ve switch koşul kontrolleri (goto kullanamıyorsunuz),
  • Döngüler (for, while, do-while ve range-based),
  • Birden fazla ifade kullanımı,
  • Başka constexpr fonksiyon kullanımı.

Şimdi hemen C++ 14 ile sunulan bu özelliğe ilişkin bir örneğe bakalım. Bunun için de faktöryel hesaplayan bir fonksiyonu inceleyelim.

Yukarıdaki kodu C++ 11 derleyicisi ile derlediğinizde, aşağıdaki hatayı ya da benzerini alırsınız:

Şimdi aynı kodu C++ 14 derleyicisinde derleyin ve sonucu görün ki bu 120 olmalı.

Burada, ilgili kod tamamen derleme zamanında hesaplanmaktadır. Peki bu bütün constexpr fonksiyonlar için geçerli mi?

Elbette hayır. Burada dikkat edilmesi gereken husus, geçirilen parametrelerin const olması ve dönüş değerinin de yine aynı şekilde const bir ifade de kullanılmasıdır. Arkada neler döndüğünü görmek için yukarıdaki kodu “Compiler Explorer‘a aktarıp, önce mevcut hali ile sonra da, yorumlu kısmı açıp, alt satırı yoruma alarak görebilirsiniz 😉

Bu kabiliyete ilişkin yapılan değişiklikleri daha detaylı görmek için, kaynaklar kısmına eklediğim ve değişiklikleri açık bir şekilde gösteren dokümana da göz atabilirsiniz.

Fonskiyonlar için dönüşü tipi çıkarımı (Return type deduction)

C++ 14 ile iyileştirme sağlanan bir diğer kabiliyet de, fonksiyonların dönüş değerinin çıkarılması. Bunu dediğimde aklınızda hemen şöyle bir soru belirmiş olabilir: C++ 11 ile bunu nasıl sağlıyorduk? Öncelikle elbette C++ 14’ün sunduğu kadar kolay ve temiz şekilde olmasada, bir seviyede sağlanmaktaydı. Bu da, lambda ve template fonksiyonları ile sağlanıyordu. Önce lambda fonksiyonlara bakalım:

Bir diğer örnek kullanım da, template fonksiyonlar aracılığı ile oluyordu. Fakat dönüş değerini belirlemek için aşağıdaki gibi bir takla atmanız gerekiyordu:

bir diğer ifade ile, dönüş değerini derleyiciye söylemek için “decltype” ibaresini kullanmanız gerekiyor. Peki, bunu C++ 14 ile artık nasıl yapabiliyoruz? Eminim hepiniz tahmin etmişsinizdir:

Tabi ki bu özellik sadece template fonksiyonlar için geçerli değil, normal fonksiyonlar için de bunu kullanabiliyoruz ve dahi recursive fonksiyonları da bu şekilde tanımlayabiliyoruz. Hemen basit örneklere bir göz atalım:

Tabi bir takım kısıtlamalar da yok değil:

  • Öncelikle dönüş değeri auto olan fonksiyon içerisindeki bütün dönüş değerleri aynı tip olmalıdır.
  • Recursive fonksiyon tanımlamalarında da, recursive çağrı öncesinde, bir dönüş yapmanız gerekiyor ama bu çok da zor olmasa gerek 😉

Evet sevgili yazılımperver dostlarım bir C++ yazımızın daha sonuna geldik, bir sonraki yazımda görüşmek dileğiyle bol kodlu günler diliyorum hepinize.

Kaynaklar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.