Menu
CoddyTech

optional, variant, any

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

Modern C++, <optional>, <variant> ve <any> başlıklarında; bulunmayabilecek değerleri işlemenize, çeşitli türlerden birini tutmanıza veya herhangi bir türü depolamanıza yardımcı olan üç sözlük türü sağlar.

std::optional<T>, var olabilecek veya olmayabilecek bir değeri temsil eder - istisna atmadan başarısız olabilecek işlevler için mükemmeldir:

#include <iostream>
#include <optional>
std::optional<int> findIndex(const std::string& str, char c) {
    for (size_t i = 0; i < str.size(); ++i) {
        if (str[i] == c) return i;
    }
    return std::nullopt;  // Değer yok
}
int main() {
    auto result = findIndex("hello", 'l');
    if (result.has_value()) {
        std::cout << "Found at: " << *result << "\n";  // 2
    }
}

std::variant<Types...>, herhangi bir anda belirtilen türlerden tam olarak birini tutan, tür güvenli bir birleşimdir:

#include <iostream>
#include <variant>
#include <string>
int main() {
    std::variant<int, double, std::string> data;
    data = 42;
    std::cout << std::get<int>(data) << "\n";
    data = "hello";
    if (std::holds_alternative<std::string>(data)) {
        std::cout << std::get<std::string>(data) << "\n";
    }
}

std::any, çalışma zamanında belirlenen herhangi bir türdeki değeri tutabilir. Değeri almak için std::any_cast kullanın:

#include <iostream>
#include <any>
int main() {
    std::any value = 10;
    std::cout << std::any_cast<int>(value) << "\n";
    value = std::string("text");
    std::cout << std::any_cast<std::string>(value) << "\n";
}

Nullable değerler için std::optional seçin, olası türleri derleme zamanında bildiğinizde std::variant kullanın ve std::any’yi yalnızca çalışma zamanında tür esnekliğine gerçekten ihtiyaç duyduğunuzda tercih edin.

challenge icon

Görev

Kolay

Modern C++ sözlük türlerinin gücünü gösteren bir yapılandırma sistemi oluşturalım. Eksik olabilecek, farklı türleri tutabilen veya çalışma zamanında tür esnekliği gerektiren değerleri işleyen esnek bir ayar yöneticisi oluşturacaksınız.

Kodunuzu üç dosya arasında düzenleyeceksiniz:

  • ConfigTypes.h: Yapılandırma değeri türlerinizi ve yardımcı işlevlerinizi tanımlayın.

    Bir dize alan ve bunu bir tamsayı olarak ayrıştırmayı deneyen parseValue adlı bir işlev oluşturun. Dize geçerli bir tamsayıyı temsil ediyorsa, tamsayıyı std::optional içinde sarılmış olarak döndürün. Ayrıştırma başarısız olursa (dize sayısal olmayan karakterler içeriyorsa), std::nullopt döndürün. Basitlik açısından, yalnızca rakamlar (ve isteğe bağlı olarak başında bir eksi işareti) içeriyorsa bir dizeyi geçerli kabul edin.

    int, double veya std::string türlerinden birini tutabilen, std::variant kullanan Setting adlı bir tür takma adı da oluşturun.

    Son olarak, bir Setting alan ve tuttuğu türü ve değeri aşağıdaki biçimde açıklayan bir dize döndüren describeSetting adlı bir işlev oluşturun:

    • int için: Integer: [value]
    • double için: Double: [value]
    • string için: String: [value]
  • DynamicStore.h: std::any kullanarak basit bir anahtar-değer deposu oluşturun.

    Her türden değeri depolayabilen bir DynamicStore sınıfı tanımlayın. Şunlara sahip olmalıdır:

    • Dize anahtarını ve bir std::any değerini alan ve bunları dahili olarak depolayan (bir std::map kullanın) set yöntemi
    • Bir anahtar alan ve std::any değerini döndüren (anahtar mevcut değilse boş bir std::any döndürün) get yöntemi
    • Anahtar mevcutsa true döndüren hasKey yöntemi
  • main.cpp: Üç girdi okuyun:
    1. Sayı olabilecek bir dize (std::optional testi için)
    2. Bir tür belirteci: int, double veya string
    3. Bu türe karşılık gelen bir değer

    Üç sözlük türünün tümünü gösterin:

    İlk olarak, ilk girdiyle parseValue işlevinizi kullanın. Bir değer içeriyorsa Parsed: [value] yazdırın. Boşsa Parse failed yazdırın.

    İkinci olarak, tür belirtecine göre bir Setting varyantı oluşturun. Tür int ise değeri tamsayı olarak depolayın. double ise double olarak depolayın. string ise dize olarak depolayın. Ardından describeSetting işlevini çağırın ve sonucu yazdırın.

    Üçüncü olarak, bir DynamicStore oluşturun, "config_loaded" dizesini "status" anahtarı altında depolayın, ardından bu değeri alın ve Status: [value] yazdırın. Değeri çıkarmak için std::any_cast<std::string> kullanın.

Örneğin, 42, int ve 100 girdileriyle:

Parsed: 42
Integer: 100
Status: config_loaded

hello, double ve 3.14 girdileriyle:

Parse failed
Double: 3.14
Status: config_loaded

-15, string ve username girdileriyle:

Parsed: -15
String: username
Status: config_loaded

Gerektiğinde uygun başlıkları eklemeyi unutmayın: <optional>, <variant>, <any>, <string> ve <map>. Varyantınızla çalışmak için std::holds_alternative ve std::get kullanın; optional'ınızı kontrol etmek için has_value() veya doğrudan boolean dönüşüm kullanın.

Kendin dene

#include <iostream>
#include <string>
#include <any>
#include "ConfigTypes.h"
#include "DynamicStore.h"

int main() {
    // Üç girdi oku
    std::string input1;  // Sayı olabilecek bir dize (std::optional test etmek için)
    std::string typeIndicator;  // Tür göstergesi: int, double veya string
    std::string value;  // Bu türe karşılık gelen değer
    
    std::cin >> input1;
    std::cin >> typeIndicator;
    std::cin >> value;
    
    // TODO: Bölüm 1 - parseValue ile std::optional'ı test et
    // parseValue fonksiyonunu input1 ile kullan
    // Eğer bir değer içeriyorsa, "Parsed: [value]" yazdır
    // If it's empty, print "Parse failed"
    
    
    // TODO: Bölüm 2 - Setting ile std::variant'ı test et
    // typeIndicator'a göre bir Setting variant oluştur
    // Tür "int" ise, value'yu tamsayı olarak sakla
    // Tür "double" ise, value'yu double olarak sakla
    // Tür "string" ise, value'yu string olarak sakla
    // Sonra describeSetting'i çağır ve sonucu yazdır
    
    
    // TODO: Bölüm 3 - DynamicStore ile std::any'yi test et
    // Bir DynamicStore oluştur
    // "config_loaded" dizesini "status" anahtarı altında sakla
    // Onu al ve yazdır: "Status: [value]"
    // Değeri çıkarmak için std::any_cast<std::string> kullan
    
    
    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