Fonksiyon Şablonları
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 64 / 104.
İki tam sayının maksimumunu bulan bir fonksiyon yazdığınızı, ardından aynı mantığa double türleri ve tekrar string türleri için de ihtiyacınız olduğunu fark ettiğinizi hayal edin. Şablonlar olmadan, her tür için neredeyse birbirinin aynısı fonksiyonlar yazardınız. Fonksiyon şablonları, mantığı bir kez yazmanıza izin vererek ve derleyicinin türe özgü sürümleri otomatik olarak oluşturmasını sağlayarak bu sorunu çözer.
Bir fonksiyon şablonu, template anahtar kelimesini ve ardından açılı ayraçlar içindeki şablon parametrelerini kullanır:
template <typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}
int main() {
std::cout << maximum(5, 3) << std::endl; // int sürümünü kullanır
std::cout << maximum(3.14, 2.71) << std::endl; // double sürümünü kullanır
std::cout << maximum('a', 'z') << std::endl; // char sürümünü kullanır
}Derleyici her çağrıyı inceler ve o belirli tür için somut bir fonksiyon oluşturur. Bu işleme şablon örneklendirme (template instantiation) denir. Gerektiğinde türü açıkça da belirtebilirsiniz:
std::cout << maximum<double>(5, 3.14) << std::endl; // double versiyonunu zorlarŞablonlar, daha da esnek tasarımlara olanak tanıyarak birden fazla tür parametresine sahip olabilir:
template <typename T, typename U>
void printPair(T first, U second) {
std::cout << first << ", " << second << std::endl;
}
printPair(42, "hello"); // T=int, U=const char*
printPair(3.14, 100); // T=double, U=intFonksiyon şablonları derleme zamanı polimorfizmi sağlar - tür, çalışma zamanında değil, kod derlendiğinde belirlenir. Bu, sanal fonksiyonlara kıyasla sıfır çalışma zamanı ek yükü anlamına gelir ve şablonları performans açısından kritik genel kodlar için ideal hale getirir.
Görev
KolayHerhangi bir uyumlu tiple çalışan yeniden kullanılabilir işlemler oluşturmak için fonksiyon şablonlarını (function templates) kullanarak bir yardımcı araç takımı oluşturalım. Genel fonksiyonlarınızı bir başlık dosyasında düzenleyecek ve ana programınızda bunların esnekliğini göstereceksiniz.
İki dosya oluşturacaksınız:
MathUtils.h: Yaygın işlemleri gerçekleştiren bir fonksiyon şablonları koleksiyonu tanımlayın:minimum— aynı tipten iki değer alan ve daha küçük olanı döndüren bir şablon fonksiyonu.clamp— üç parametre alan bir şablon fonksiyonu: bir değer, bir alt sınır ve bir üst sınır. Sınırlar içine kısıtlanmış değeri döndürür (değer alt sınırdan küçükse alt sınırı, üst sınırdan büyükse üst sınırı, aksi takdirde değerin kendisini döndürür).swapValues— aynı tipten iki referans alan ve değerlerini değiştiren bir şablon fonksiyonu.main.cpp: Altı girdi okuyun (her biri ayrı bir satırda):- Birinci tam sayı
- İkinci tam sayı
- Sınırlandırılacak (clamp) bir double değer
- Alt sınır (double)
- Üst sınır (double)
- Bir karakter
Şablonlarınızı şunları yaparak gösterin:
- İki tam sayının minimumunu bulun ve şunu yazdırın:
Min of <a> and <b>: <result> 'm'karakteri ile girdi karakterinizin minimumunu bulun ve şunu yazdırın:Min of m and <char>: <result>- Double değeri sınırlandırın ve şunu yazdırın:
Clamp <value> to [<low>, <high>]: <result> - Birinci tam sayıyı [0, 100] aralığına sınırlandırın ve şunu yazdırın:
Clamp <value> to [0, 100]: <result> - İki tam sayıyı takas edin ve şunu yazdırın:
After swapValues: <a>, <b>
Örneğin, 25, 10, 3.7, 1.0, 5.0 ve z girdileriyle:
Min of 25 and 10: 10
Min of m and z: m
Clamp 3.7 to [1, 5]: 3.7
Clamp 25 to [0, 100]: 25
After swapValues: 10, 25Her bir şablon fonksiyonunun tam sayılar, double'lar ve karakterlerle nasıl sorunsuz çalıştığına dikkat edin — derleyici, kullandığınız her tip için uygun sürümü oluşturur. swapValues fonksiyonunuz, referanslar aracılığıyla orijinal değişkenleri değiştirmelidir; bu da şablonların tıpkı normal fonksiyonlar gibi referans parametreleriyle çalıştığını gösterir.
Kopya kağıdı
Fonksiyon şablonları, birden fazla türle çalışan genel fonksiyonlar yazmanıza olanak tanır. Şablon parametrelerinin ardından template anahtar kelimesini kullanın:
template <typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}Derleyici, şablon örneği oluşturma (template instantiation) yoluyla otomatik olarak türe özgü sürümler oluşturur:
maximum(5, 3); // int sürümünü oluşturur
maximum(3.14, 2.71); // double sürümünü oluşturur
maximum('a', 'z'); // char sürümünü oluştururGerektiğinde türü açıkça belirtebilirsiniz:
maximum<double>(5, 3.14); // double sürümünü zorlarŞablonlar birden fazla tür parametresini destekler:
template <typename T, typename U>
void printPair(T first, U second) {
std::cout << first << ", " << second << std::endl;
}
printPair(42, "hello"); // T=int, U=const char*Şablonlar, orijinal değerleri değiştirmek için referans parametreleriyle çalışır:
template <typename T>
void swapValues(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}Fonksiyon şablonları, sıfır çalışma zamanı yükü ile derleme zamanı polimorfizmi sağlayarak onları performans açısından kritik genel kodlar için ideal hale getirir.
Kendin dene
#include <iostream>
#include "MathUtils.h"
using namespace std;
int main() {
// Girdileri oku
int a, b;
double value, low, high;
char ch;
cin >> a;
cin >> b;
cin >> value;
cin >> low;
cin >> high;
cin >> ch;
// TODO: İki tam sayının minimumunu bulmak için minimum şablonunu kullanın
// Yazdır: "Min of <a> and <b>: <result>"
// TODO: 'm' ve girdi karakterinin minimumunu bulmak için minimum şablonunu kullanın
// Yazdır: "Min of m and <char>: <result>"
// TODO: double değeri üzerinde clamp şablonunu kullanın
// Yazdır: "Clamp <value> to [<low>, <high>]: <result>"
// TODO: [0, 100] aralığındaki ilk tam sayı üzerinde clamp şablonunu kullanın
// Yazdır: "Clamp <value> to [0, 100]: <result>"
// TODO: İki tam sayı üzerinde swapValues şablonunu kullanın
// Yazdır: "After swapValues: <a>, <b>"
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic Konteyner