SFINAE
İşlevleri koşullu olarak etkinleştirin
SFINAE, CoddyKit'te ücretsiz bir C++ Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C++ Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C++ Academy kursu toplamda 4 dersten oluşur.
SFINAE Ne Anlama Gelir
SFINAE, "Substitution Failure Is Not An Error" ifadesinin kısaltmasıdır. Derleyici şablon bağımsız değişkenlerini yerine koyduğunda sonuç hatalı biçimlenmişse bu aday, ciddi bir hataya yol açmak yerine yalnızca kaldırılır.
- Koşullu aşırı yüklemeleri etkinleştirir.
- Derleme zamanında seçimin temelini oluşturur.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
isOdd(T n) { return n % 2 != 0; }
int main() {
std::cout << std::boolalpha << isOdd(3) << '\n';
return 0;
}Yerine Koyma Hatası Uygulamada
Bir türü yerine koymak işlevin imzasını geçersiz kılarsa derleyici bu işlevi sessizce atlar ve diğer adayları değerlendirmeye devam eder.
#include <iostream>
template <typename T>
auto sizeOfValue(T t) -> decltype(t.size()) { return t.size(); }
int main() {
std::string s = "hello";
std::cout << sizeOfValue(s) << '\n';
return 0;
}İki Aşırı Yükleme, Biri Kazanır
Belirli bir tür için tam olarak birinin başarıyla yerine konacağı iki aşırı yükleme sağlayın. SFINAE geçersiz olanı eler.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, const char*>::type
name() { return "integral"; }
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, const char*>::type
name() { return "floating"; }
int main() {
std::cout << name<int>() << ' ' << name<double>() << '\n';
return 0;
}decltype ve İfade SFINAE'si
Dönüş türündeki bir ifadeye decltype uygulamak, bir işlevin yalnızca o ifade tür için geçerliyse var olmasını sağlar.
#include <iostream>
template <typename T>
auto tryDouble(T x) -> decltype(x + x) { return x + x; }
int main() {
std::cout << tryDouble(21) << '\n';
std::cout << tryDouble(2.5) << '\n';
return 0;
}Üye Algılama
Klasik bir SFINAE tekniği, onu kullanan bir ifadenin derlenip derlenmediğini kontrol ederek bir türün belirli bir üyeye sahip olup olmadığını algılar.
#include <iostream>
#include <type_traits>
#include <vector>
template <typename T>
auto hasSize(int) -> decltype(std::declval<T>().size(), std::true_type{});
template <typename T>
std::false_type hasSize(...);
int main() {
std::cout << std::boolalpha;
std::cout << decltype(hasSize<std::vector<int>>(0))::value << '\n';
std::cout << decltype(hasSize<int>(0))::value << '\n';
return 0;
}... Geri Dönüşü
... alan bir aşırı yükleme (değişken sayıda bağımsız değişken), en düşük önceliğe sahiptir. SFINAE kısıtlı aşırı yükleme başarısız olduğunda tüm durumları karşılayan seçenek olarak görev yapar.
#include <iostream>
template <typename T>
auto pick(int) -> decltype(T{}.value, void()) { std::cout << "has value\n"; }
template <typename T>
void pick(...) { std::cout << "no value\n"; }
struct WithValue { int value = 0; };
int main() {
pick<WithValue>(0);
pick<int>(0);
return 0;
}void_t
C++17'nin std::void_t özelliği algılamayı basitleştirir: düzgün biçimlenmiş tüm türleri void türüne eşler; böylece bir özelleştirme yalnızca denetlenen ifade geçerliyse etkinleşir.
#include <iostream>
#include <type_traits>
#include <vector>
template <typename T, typename = void>
struct HasSize : std::false_type {};
template <typename T>
struct HasSize<T, std::void_t<decltype(std::declval<T>().size())>> : std::true_type {};
int main() {
std::cout << std::boolalpha;
std::cout << HasSize<std::vector<int>>::value << '\n';
std::cout << HasSize<int>::value << '\n';
return 0;
}Neden Doğrudan Hata Vermiyor
SFINAE olmadan geçersiz bir yerine koyma ciddi bir derleme hatası olur ve bu durumdan kurtarılamazdı. SFINAE bunu sessizce "aday değil" durumuna dönüştürür.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_pointer<T>::value, bool>::type
isNull(T p) { return p == nullptr; }
int main() {
int x = 0;
std::cout << std::boolalpha << isNull(&x) << '\n';
return 0;
}Etiket Dağıtımı Seçeneği
SFINAE'nin okunması zor olabilir. Etiket dağıtımı bunun yerine küçük etiket türleri ve aşırı yük çözümlemesi kullanarak bir uygulama seçer.
#include <iostream>
#include <type_traits>
template <typename T>
void impl(T v, std::true_type) { std::cout << "integral: " << v << '\n'; }
template <typename T>
void impl(T v, std::false_type) { std::cout << "other: " << v << '\n'; }
template <typename T>
void handle(T v) { impl(v, std::is_integral<T>{}); }
int main() {
handle(5);
handle(2.5);
return 0;
}SFINAE ve constexpr if
C++17'de if constexpr, tek bir işlev içindeki dallanma için çoğu zaman SFINAE'nin yerini alır; çünkü kullanılmayan dallar derleme zamanında elenir.
#include <iostream>
#include <type_traits>
template <typename T>
void describe(T v) {
if constexpr (std::is_integral<T>::value) {
std::cout << "integral: " << v << '\n';
} else {
std::cout << "other: " << v << '\n';
}
}
int main() {
describe(7);
describe(3.14);
return 0;
}Hepsini Bir Araya Getirme
SFINAE, aşırı yükleme düzeyinde tür özelliklerine göre ayrı işlev şablonları arasında seçim yapmanız gerektiğinde büyük yarar sağlar.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_signed<T>::value, T>::type
absValue(T v) { return v < 0 ? -v : v; }
int main() {
std::cout << absValue(-9) << '\n';
return 0;
}Kısa Kontrol
SFINAE'yi anlayıp anlamadığınızı test edin.
Özet
SFINAE'yi öğrendiniz:
- geçersiz bir yerine koyma hata vermek yerine adayı kaldırır
- işlevleri koşullu olarak etkinleştirmek için
enable_if,decltypevevoid_tile kullanılır ...aşırı yüklemesi geri dönüş seçeneği olarak görev yapar- modern seçenekler arasında etiket dağıtımı ve
if constexprbulunur
Sırada klasik enable_if kalıplarına ayrıntılı olarak odaklanacaksınız.
Sıkça Sorulan Sorular
“SFINAE” dersi ücretsiz mi?
Evet — “SFINAE” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C++ Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C++ Academy kursu toplamda 4 dersten oluşur.
“SFINAE” dersinde ne öğreneceğim?
İşlevleri koşullu olarak etkinleştirin C++ Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C++ Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C++ Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“SFINAE” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C++ Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C++ Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.