-
Sadrazamv4
ig:sadrazam_v4 tg: Sadrazam.spy
/*
================================================================================
🚀 MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 6 🚀
Template Metaprogramming, SFINAE & C++20 Concepts / Constraints
================================================================================
GİRİŞ 📌
--------------------------------------------------------------------------------
Beşinci bölümde STL kapsayıcılarının iç mimarisini, `std::vector` bellek büyüme
ve reallocation mekanizmasını, `std::map` ile `std::unordered_map` arasındaki
algoritmik ve donanımsal farkları incelemiştik.
Bu bölümde C++'ın en güçlü yönlerinden biri olan **Şablon Programlama (Template
Metaprogramming)** dünyasına adım atıyoruz. Fonksiyon/Sınıf şablon özelleştirmelerini,
derleme zamanı polimorfizminin temeli **SFINAE** tekniğini ve C++20 ile şablon
yazımını kökten değiştiren **Concepts & Constraints** mekanizmasını ele alacağız.
*/
#include <iostream>
#include <type_traits>
#include <concepts>
#include <string>
#include <vector>
// =============================================================================
// 1. ŞABLON ÖZELLEŞTİRME (EXPLICIT & PARTIAL SPECIALIZATION) 🧩
// =============================================================================
/*
* Şablonlar, tip bağımsız genel kod yazmamızı sağlar. Ancak belirli tipler
* için özel optimizasyon veya farklı davranış gerekebilir.
*/
// Genel Şablon (Primary Template)
template<typename T>
struct TypeSerializer {
static void serialize(const T& val) {
std::cout << "📦 Genel Nesne Serialized: " << val << "\n";
}
};
// Tam Özelleştirme (Explicit / Full Specialization)
template<>
struct TypeSerializer<std::string> {
static void serialize(const std::string& val) {
std::cout << "🔤 String Tipi Özel Metodla Serialized: \"" << val << "\"\n";
}
};
// Kısmi Özelleştirme (Partial Specialization) - Yalnızca Sınıf Şablonlarında Geçerlidir!
template<typename T>
struct TypeSerializer<std::vector<T>> {
static void serialize(const std::vector<T>& vec) {
std::cout << "📚 Vector [Boyut: " << vec.size() << "] Elemanları:\n";
for (const auto& elem : vec) {
std::cout << " - ";
TypeSerializer<T>::serialize(elem);
}
}
};
// =============================================================================
// 2. CLASSIC SFINAE: SUBSTITUTION FAILURE IS NOT AN ERROR 🛠️
// =============================================================================
/*
* SFINAE İlkesi: Şablon parametreleri yerine gerçek tipler koyulurken (substitution)
* geçersiz bir tip/ifade oluşursa, bu durum DERLEME HATASI OLUŞTURMAZ.
* Derleyici bu fonksiyon yüklemesini (overload) aday listesinden sessizce çıkarır.
*
* `std::enable_if_t` ile SFINAE (C++11/14 Yöntemi):
*/
// Yalnızca tamsayı (integral) tipler için aktif olan fonksiyon yüklemesi
template<typename T, typename std::enable_if_t<std::is_integral_v<T>, int> = 0>
void process_number(T val) {
std::cout << "🔢 Tamsayı İşleniyor (SFINAE): " << val << "\n";
}
// Yalnızca ondalıklı (floating_point) tipler için aktif olan fonksiyon yüklemesi
template<typename T, typename std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
void process_number(T val) {
std::cout << "🌊 Ondalıklı Sayı İşleniyor (SFINAE): " << val << "\n";
}
// =============================================================================
// 3. MODERN C++20 CONCEPTS VE CONSTRAINTS (`requires`) ⚙️
// =============================================================================
/*
* SFINAE tekniği güçlü olsa da karmaşık hata mesajlarına ve okunması zor koda
* neden olur. ISO C++20 ile gelen Concepts bu sorunu çözer:
* 1. Tip kısıtlamalarını net, bildirisel (declarative) bir sözdizimiyle ifade eder.
* 2. İhlal durumunda derleyicinin İNANILMAZ NET VE ANLAŞILIR hata vermesini sağlar.
* 3. Derleme sürelerini (compile-time) hızlandırır.
*/
// A) Özel Concept Tanımlama (Custom Concept)
template<typename T>
concept Numeric = std::is_arithmetic_v<T>; // Hem int hem float tiplerini kapsar
template<typename T>
concept Printable = requires(T a) {
{ std::cout << a } -> std::same_as<std:
stream&>; // std::cout << a ifadesi geçerli olmalı!
};
// B) Concept Kullanım Yöntemleri (4 Farklı Syntax)
// Yöntem 1: `requires` maddesi (Requires Clause)
template<typename T>
requires Numeric<T>
T multiply_v1(T a, T b) {
return a * b;
}
// Yöntem 2: Şablon parametresinde kısıtlama (Constrained Template Parameter)
template<Numeric T>
T multiply_v2(T a, T b) {
return a * b;
}
// Yöntem 3: Terzihane 'requires' ifadesi ile (Trailing Requires Clause)
template<typename T>
T multiply_v3(T a, T b) requires Numeric<T> {
return a * b;
}
// Yöntem 4: Auto & Concise Syntax (En Modern ve Temiz Sözdizimi)
Numeric auto multiply_v4(Numeric auto a, Numeric auto b) {
return a * b;
}
// C) Çoklu Kısıtlama ve Bileşik Concept (Conjunction)
template<typename T>
requires Numeric<T> && Printable<T>
void print_numeric_value(T val) {
std::cout << "🎯 Kısıtlanmış Değer: " << val << "\n";
}
// =============================================================================
// 4. MAIN VE PROGRAM GİRİŞ NOKTASI 🚀
// =============================================================================
int main() {
std::cout << "============================================" << std::endl;
std::cout << " ISO C++17/20/23 Dersleri - Bolum 6 " << std::endl;
std::cout << "============================================" << std::endl << std::endl;
std::cout << "--- 1. Template Specialization ---" << std::endl;
TypeSerializer<int>::serialize(42);
TypeSerializer<std::string>::serialize("ISO C++20");
std::vector<int> numbers{1, 2, 3};
TypeSerializer<std::vector<int>>::serialize(numbers);
std::cout << "\n--- 2. Classic SFINAE (std::enable_if) ---" << std::endl;
process_number(100); // SFINAE -> Integer Overload
process_number(3.1415); // SFINAE -> Floating Point Overload
std::cout << "\n--- 3. ISO C++20 Concepts & Constraints ---" << std::endl;
std::cout << "multiply_v4(5, 4): " << multiply_v4(5, 4) << "\n";
std::cout << "multiply_v4(2.5, 3.0): " << multiply_v4(2.5, 3.0) << "\n";
print_numeric_value(2026);
// Eğer aşağıdaki satırın yorumu kaldırılırsa:
// multiply_v4("Hata", "Test");
// Derleyici doğrudan SFINAE karmaşası yerine:
// "error: constraints not satisfied for concept 'Numeric<const char*>'" şeklinde net bir hata verir!
std::cout << "\n✔ Bolum 6 Kavramları Başarıyla İşlendi!" << std::endl;
return 0;
}
/*
================================================================================
BÖLÜM ÖZETİ VE GELECEK BÖLÜM 📝
--------------------------------------------------------------------------------
Bu bölümde C++ Metaprogramming temellerini, SFINAE tekniğini, derleme zamanı
tip kontrollerini ve C++20 Concepts / Constraints devrimini inceledik.
Gelecek Bölüm (Bölüm 7):
- Modern C++ Lambda İfadeleri & Closure Tipleri ⚡
- Capture List (By-Value, By-Reference, Init-Capture)
- `mutable`, `constexpr` ve `noexcept` Lambdalar
- ISO C++20 Generic & Template Lambdalar (`[]<typename T>(T x)`)
- `std::function` vs Templated Callable Performance (Maliyet Analizi
)
================================================================================
Bölüm 6 Sonu.
================================================================================
*/
================================================================================
🚀 MODERN ISO C++ PROGRAMLAMA DERSLERİ: BÖLÜM 6 🚀
Template Metaprogramming, SFINAE & C++20 Concepts / Constraints
================================================================================
GİRİŞ 📌
--------------------------------------------------------------------------------
Beşinci bölümde STL kapsayıcılarının iç mimarisini, `std::vector` bellek büyüme
ve reallocation mekanizmasını, `std::map` ile `std::unordered_map` arasındaki
algoritmik ve donanımsal farkları incelemiştik.
Bu bölümde C++'ın en güçlü yönlerinden biri olan **Şablon Programlama (Template
Metaprogramming)** dünyasına adım atıyoruz. Fonksiyon/Sınıf şablon özelleştirmelerini,
derleme zamanı polimorfizminin temeli **SFINAE** tekniğini ve C++20 ile şablon
yazımını kökten değiştiren **Concepts & Constraints** mekanizmasını ele alacağız.
*/
#include <iostream>
#include <type_traits>
#include <concepts>
#include <string>
#include <vector>
// =============================================================================
// 1. ŞABLON ÖZELLEŞTİRME (EXPLICIT & PARTIAL SPECIALIZATION) 🧩
// =============================================================================
/*
* Şablonlar, tip bağımsız genel kod yazmamızı sağlar. Ancak belirli tipler
* için özel optimizasyon veya farklı davranış gerekebilir.
*/
// Genel Şablon (Primary Template)
template<typename T>
struct TypeSerializer {
static void serialize(const T& val) {
std::cout << "📦 Genel Nesne Serialized: " << val << "\n";
}
};
// Tam Özelleştirme (Explicit / Full Specialization)
template<>
struct TypeSerializer<std::string> {
static void serialize(const std::string& val) {
std::cout << "🔤 String Tipi Özel Metodla Serialized: \"" << val << "\"\n";
}
};
// Kısmi Özelleştirme (Partial Specialization) - Yalnızca Sınıf Şablonlarında Geçerlidir!
template<typename T>
struct TypeSerializer<std::vector<T>> {
static void serialize(const std::vector<T>& vec) {
std::cout << "📚 Vector [Boyut: " << vec.size() << "] Elemanları:\n";
for (const auto& elem : vec) {
std::cout << " - ";
TypeSerializer<T>::serialize(elem);
}
}
};
// =============================================================================
// 2. CLASSIC SFINAE: SUBSTITUTION FAILURE IS NOT AN ERROR 🛠️
// =============================================================================
/*
* SFINAE İlkesi: Şablon parametreleri yerine gerçek tipler koyulurken (substitution)
* geçersiz bir tip/ifade oluşursa, bu durum DERLEME HATASI OLUŞTURMAZ.
* Derleyici bu fonksiyon yüklemesini (overload) aday listesinden sessizce çıkarır.
*
* `std::enable_if_t` ile SFINAE (C++11/14 Yöntemi):
*/
// Yalnızca tamsayı (integral) tipler için aktif olan fonksiyon yüklemesi
template<typename T, typename std::enable_if_t<std::is_integral_v<T>, int> = 0>
void process_number(T val) {
std::cout << "🔢 Tamsayı İşleniyor (SFINAE): " << val << "\n";
}
// Yalnızca ondalıklı (floating_point) tipler için aktif olan fonksiyon yüklemesi
template<typename T, typename std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
void process_number(T val) {
std::cout << "🌊 Ondalıklı Sayı İşleniyor (SFINAE): " << val << "\n";
}
// =============================================================================
// 3. MODERN C++20 CONCEPTS VE CONSTRAINTS (`requires`) ⚙️
// =============================================================================
/*
* SFINAE tekniği güçlü olsa da karmaşık hata mesajlarına ve okunması zor koda
* neden olur. ISO C++20 ile gelen Concepts bu sorunu çözer:
* 1. Tip kısıtlamalarını net, bildirisel (declarative) bir sözdizimiyle ifade eder.
* 2. İhlal durumunda derleyicinin İNANILMAZ NET VE ANLAŞILIR hata vermesini sağlar.
* 3. Derleme sürelerini (compile-time) hızlandırır.
*/
// A) Özel Concept Tanımlama (Custom Concept)
template<typename T>
concept Numeric = std::is_arithmetic_v<T>; // Hem int hem float tiplerini kapsar
template<typename T>
concept Printable = requires(T a) {
{ std::cout << a } -> std::same_as<std:
};
// B) Concept Kullanım Yöntemleri (4 Farklı Syntax)
// Yöntem 1: `requires` maddesi (Requires Clause)
template<typename T>
requires Numeric<T>
T multiply_v1(T a, T b) {
return a * b;
}
// Yöntem 2: Şablon parametresinde kısıtlama (Constrained Template Parameter)
template<Numeric T>
T multiply_v2(T a, T b) {
return a * b;
}
// Yöntem 3: Terzihane 'requires' ifadesi ile (Trailing Requires Clause)
template<typename T>
T multiply_v3(T a, T b) requires Numeric<T> {
return a * b;
}
// Yöntem 4: Auto & Concise Syntax (En Modern ve Temiz Sözdizimi)
Numeric auto multiply_v4(Numeric auto a, Numeric auto b) {
return a * b;
}
// C) Çoklu Kısıtlama ve Bileşik Concept (Conjunction)
template<typename T>
requires Numeric<T> && Printable<T>
void print_numeric_value(T val) {
std::cout << "🎯 Kısıtlanmış Değer: " << val << "\n";
}
// =============================================================================
// 4. MAIN VE PROGRAM GİRİŞ NOKTASI 🚀
// =============================================================================
int main() {
std::cout << "============================================" << std::endl;
std::cout << " ISO C++17/20/23 Dersleri - Bolum 6 " << std::endl;
std::cout << "============================================" << std::endl << std::endl;
std::cout << "--- 1. Template Specialization ---" << std::endl;
TypeSerializer<int>::serialize(42);
TypeSerializer<std::string>::serialize("ISO C++20");
std::vector<int> numbers{1, 2, 3};
TypeSerializer<std::vector<int>>::serialize(numbers);
std::cout << "\n--- 2. Classic SFINAE (std::enable_if) ---" << std::endl;
process_number(100); // SFINAE -> Integer Overload
process_number(3.1415); // SFINAE -> Floating Point Overload
std::cout << "\n--- 3. ISO C++20 Concepts & Constraints ---" << std::endl;
std::cout << "multiply_v4(5, 4): " << multiply_v4(5, 4) << "\n";
std::cout << "multiply_v4(2.5, 3.0): " << multiply_v4(2.5, 3.0) << "\n";
print_numeric_value(2026);
// Eğer aşağıdaki satırın yorumu kaldırılırsa:
// multiply_v4("Hata", "Test");
// Derleyici doğrudan SFINAE karmaşası yerine:
// "error: constraints not satisfied for concept 'Numeric<const char*>'" şeklinde net bir hata verir!
std::cout << "\n✔ Bolum 6 Kavramları Başarıyla İşlendi!" << std::endl;
return 0;
}
/*
================================================================================
BÖLÜM ÖZETİ VE GELECEK BÖLÜM 📝
--------------------------------------------------------------------------------
Bu bölümde C++ Metaprogramming temellerini, SFINAE tekniğini, derleme zamanı
tip kontrollerini ve C++20 Concepts / Constraints devrimini inceledik.
Gelecek Bölüm (Bölüm 7):
- Modern C++ Lambda İfadeleri & Closure Tipleri ⚡
- Capture List (By-Value, By-Reference, Init-Capture)
- `mutable`, `constexpr` ve `noexcept` Lambdalar
- ISO C++20 Generic & Template Lambdalar (`[]<typename T>(T x)`)
- `std::function` vs Templated Callable Performance (Maliyet Analizi
)
================================================================================
Bölüm 6 Sonu.
================================================================================
*/
🔒 Bu içeriği görmek için giriş yapın