Menu
Coddy logo textTech

Şablon Özelleştirme

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 66 / 104.

Bazen genel bir şablon her tür için iyi çalışmaz. Örneğin, C tarzı dizeleri > ile karşılaştırmak gerçek metni değil, işaretçi adreslerini karşılaştırır. Şablon özelleştirmesi, diğer her şey için genel sürümü korurken belirli türler için özel bir uygulama sağlamanıza olanak tanır.

Tam özelleştirme, belirli bir tür için şablonun tamamını değiştirir. Bunu boş bir şablon parametre listesiyle bildirir ve somut türü belirtirsin:

// Birincil şablon
template <typename T>
class Printer {
public:
    void print(T value) {
        std::cout << value << std::endl;
    }
};

// const char* için tam özelleştirme
template <>
class Printer<const char*> {
public:
    void print(const char* value) {
        std::cout << "String: " << value << std::endl;
    }
};

Printer<int> intPrinter;
intPrinter.print(42);           // Çıktı: 42

Printer<const char*> strPrinter;
strPrinter.print("hello");      // Çıktı: String: hello

Fonksiyon şablonları da özelleştirilebilir:

template <typename T>
bool isEqual(T a, T b) {
    return a == b;
}

template <>
bool isEqual<const char*>(const char* a, const char* b) {
    return std::strcmp(a, b) == 0;
}

isEqual(5, 5);              // Genel sürümü kullanır
isEqual("hi", "hi");        // Özelleştirilmiş sürümü kullanır

Derleyici her zaman en özel eşleşmeyi tercih eder - kullanılan tam tür için bir özelleştirme varsa, generic şablon yerine o seçilir.

challenge icon

Görev

Kolay

Her şey için genel bir geri dönüş davranışını korurken, şablon özelleştirmenin belirli türler için davranışı nasıl özelleştirmenize olanak tanıdığını gösteren tür farkındalıklı bir biçimlendirici sistemi oluşturalım.

Şablon kodunuzu düzenlemek için iki dosya oluşturacaksınız:

  • Formatter.h: Görüntüleme amacıyla değerleri biçimlendiren Formatter adlı bir sınıf şablonu tanımlayın. Genel şablonunuz herhangi bir türle çalışmalı; ancak özel işlem gerektiren türler için özelleştirilmiş sürümler de oluşturacaksınız.

    Birincil Formatter şablonu şunlara sahip olmalıdır:

    • T türünde bir değer alan ve format() yazdıran bir Value: <value> yöntemi

    1 veya 0 yerine insan tarafından okunabilir metin yazdıran bool için tam bir özelleştirme oluşturun:

    • format() veya Boolean: true yazdırması gereken Boolean: false yöntemi

    Dizelerin etrafına tırnak işaretleri ekleyen const char* için tam bir özelleştirme oluşturun:

    • format() yazdırması gereken String: "<value>" yöntemi

    Ayrıca aynı türden iki değer alan ve bunları formatPair biçiminde birlikte yazdıran Pair: [<first>, <second>] adlı bir işlev şablonu oluşturun.

    Her dizeyi tırnak içine alan formatPair için bir const char* özelleştirmesi oluşturun: Pair: ["<first>", "<second>"]

  • main.cpp: Dört girdi okuyun (her biri ayrı bir satırda):
    1. Bir tamsayı
    2. Bir double
    3. Dize olarak bir boolean (true veya false)
    4. Bir dize değeri

    Uygun Formatter nesneleri oluşturarak ve her tür için format() çağrısı yaparak biçimlendiricilerinizi gösterin:

    1. Tamsayıyı Formatter<int> kullanarak biçimlendirin
    2. Double değerini Formatter<double> kullanarak biçimlendirin
    3. Boolean değerini Formatter<bool> kullanarak biçimlendirin (önce dize girdisini bool değerine dönüştürün)
    4. Dizeyi Formatter<const char*> kullanarak biçimlendirin

    Ardından işlev şablonu özelleştirmesini gösterin:

    1. İki tamsayıyla formatPair çağrısı yapın: 10 ve 20
    2. İki C dizesiyle formatPair çağrısı yapın: "hello" ve "world"

Örneğin girdiler 42, 3.14, true ve Hello olduğunda:

Value: 42
Value: 3.14
Boolean: true
String: "Hello"
Pair: [10, 20]
Pair: ["hello", "world"]

Genel şablonun tamsayıları ve double değerlerini aynı şekilde işlerken, bool ve const char* için özelleştirilmiş sürümlerin özel biçimlendirme sağladığına dikkat edin. Derleyici, kullandığınız her tür için en özgül eşleşmeyi otomatik olarak seçer.

Kendin dene

#include <iostream>
#include <string>
#include "Formatter.h"

using namespace std;

int main() {
    // Girdileri oku
    int intVal;
    double doubleVal;
    string boolStr;
    string strVal;
    
    cin >> intVal;
    cin >> doubleVal;
    cin >> boolStr;
    cin >> strVal;
    
    // String'i bool'a dönüştür
    bool boolVal = (boolStr == "true");
    
    // TODO: Formatter<int> oluştur ve tamsayıyı biçimlendir
    
    // TODO: Formatter<double> oluştur ve double'ı biçimlendir
    
    // TODO: Formatter<bool> oluştur ve boolean'ı biçimlendir
    
    // TODO: Formatter<const char*> oluştur ve string'i biçimlendir
    // İpucu: const char* almak için strVal.c_str() kullan
    
    // TODO: formatPair'i iki tamsayı ile çağır: 10 ve 20
    
    // TODO: formatPair'i iki C-string ile çağır: "hello" ve "world"
    
    return 0;
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online C++ derleyicisi