Sanal üye işlevlerinin ek yükünü önlemek için CRTP'yi C++'da nasıl kullanabilirim?Dinamik polimorfizmden kaçınmak için CRTP
cevap
CRTP'a bakmak zorundaydım. Ancak bunu yaptıktan sonra, Static Polymorphism hakkında bir şeyler buldum. Bu sorunun cevabı olduğundan şüpheleniyorum.
ATL'un bu modeli oldukça kapsamlı bir şekilde kullandığı ortaya çıkıyor.
This Vikipedi cevabı ihtiyacınız olan her şeye sahiptir. Yani: Bu aslında ne kadar satın aldığımı bilmeme rağmen.
- Bellek:: Sanal fonksiyonu
- Süre başına bir fonksiyon işaretçisi: Tek işlev işaretçisi çağrı
cRTP yükü iken sanal bir işlev çağrısı havai (tabii bağımlı derleyici,) 'dir statik polimorfizmidir:
- Bellek: bir fonk: Çoğaltma Base şablon örnekleme
- Süre başına tion pointer call + her ne yapıyor static_cast yapıyor
Aslında, şablon başına temelin çoğaltılması bir yanılsamadır, çünkü (hala bir vtable'ınız yoksa) derleyici tabanın depolanmasını birleştirir ve sizin için tek bir yapıya türetilir.İşlev işaretçisi çağrısı, derleyici (static_cast bölümü) tarafından da optimize edilmiştir. –
Bu arada, CRTP analiziniz yanlış. Olması gereken: Bellek: Dean Michael'ın dediği gibi hiçbir şey yok. Çalışma Zamanı: Alıştırmanın tüm noktası olan sanal değil, bir (daha hızlı) statik işlev çağrısı. static_cast hiçbir şey yapmaz, sadece kodun derlenmesine izin verir. –
Benim esas nokta, tüm şablon örneklerinde temel kodun çoğaltılacağıdır (konuştuğunuz çok birleştirici). Şablon parametresine dayanan sadece bir yöntemle bir şablona sahip olmak; Diğer her şey bir temel sınıfta daha iyidir, aksi takdirde birden çok kez ('birleştirilir') çekilir. – user23167
Kendimi iyi CRTP tartışmalar için arıyorum. Todd Veldhuizen Techniques for Scientific C++, bunun için harika bir kaynaktır (1.3) ve ifade şablonları gibi diğer birçok gelişmiş tekniktir.
Ayrıca, Coplien'in orijinal C++ Gems makalesinin çoğunu Google kitaplarında okuyabileceğinizi öğrendim. Belki de durum böyle.
@fizzer Size önerdiğiniz parçayı okudum, ancak yine de
@AntonDaneyko Bir temel örnekte, temel sınıfın toplamı, örneğin "bir alanın alanı" olarak adlandırılır, örneğin bir kare gibi varsayılan uygulama ile. Bu durumda CRTP'nin hedefi, en türetilmiş uygulamayı çözmektir. " Bir trapezoid "vb. türetilmiş davranış gerekli olana kadar şekil olarak trapezoid'e başvurabilirken. Normalde" dynamic_cast "veya sanal yöntemlere ihtiyacınız olduğunda. –
İki yol vardır.
ilk türleri yapısına statik bir arayüz belirterek olup:
template <class Derived>
struct base {
void foo() {
static_cast<Derived *>(this)->foo();
};
};
struct my_type : base<my_type> {
void foo(); // required to compile.
};
struct your_type : base<your_type> {
void foo(); // required to compile.
};
ikinci referans ile taban veya işaretçi ile taban deyim ve kullanımından kaçınmak sürmektir derleme zamanında kablolama.
template <class T> // T is deduced at compile-time
void bar(base<T> & obj) {
obj.foo(); // will do static dispatch
}
struct not_derived_from_base { }; // notice, not derived from base
// ...
my_type my_instance;
your_type your_instance;
not_derived_from_base invalid_instance;
bar(my_instance); // will call my_instance.foo()
bar(your_instance); // will call your_instance.foo()
bar(invalid_instance); // compile error, cannot deduce correct overload
Yani yapı/arayüz tanımı ve işlevleri derleme zamanı tür kesinti birleştirerek yerine dinamik sevk statik sevkini yapmak için izin verir: Yukarıdaki tanım kullanarak, bu gibi bakmak şablon işlevleri olabilir. Bu statik polimorfizmin özüdür.
- 1. cRTP
- 2. kaçınmak
- 3. CRTP kod şu var
- 4. constexpr ve cRTP: derleyici anlaşmazlık
- 5. CRTP with Protected Türetilmiş Üye
- 6. tuşundaki menüyü görüntülemekten kaçınmak için tıklayın
- 7. Python: sonsuz döngüden kaçınmak için __getattribute__
- 8. kaçınmak MissingBackpressureException istisnalar
- 9. Kendiliğinden rastgele yürümeden kaçınmak
- 10. Sürekli çarpışmalardan kaçınmak - use_once?
- 11. CRTP ve typedef kullanan "Inherited" tipleri
- 12. Bağımlılık yaratmadan sihir numaralarından kaçınmak
- 13. Python'da uzun satır kodlardan kaçınmak
- 14. Birden çok kez dökümden kaçınmak
- 15. boyutlandırma Tkinter OptionMenu düğmesine kaçınmak
- 16. X-Frame-Options başlığını eklemekten kaçınmak için Sinatra'yı nasıl kullanırım?
- 17. Matlab dizisine erişimde döngüden kaçınmak için zaten var mı?
- 18. Yinelenen anahtarlardan kaçınmak için txMongo ile nasıl eklenir?
- 19. Sihirli sayılardan kaçınmak için, haskell'deki sabitleri nasıl kullanırım?
- 20. İşlevsel stil JavaScript: argüman mutasyonundan kaçınmak için iyi bir uygulama?
- 21. Yükü günlüğe kaydetmekten kaçınmak için TABLO DÜZENLE TABLOSU YAPMALIYOR MI?
- 22. CRTP kullanırken hatalar nasıl önlenir? <a href="http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern">CRTP</a> kullanma
- 23. Dinamik <T> için dinamik tip?
- 24. Konsolu yazdırılan dizgeye yazdırmaktan kaçınmak (RStudio)
- 25. CMake içinde alıntı yapmaktan kaçınmak add_custom_command
- 26. CRTP kullanarak statik polimorfizmde saf sanal işlevi taklit mümkün mü?
- 27. Karma jeneratörler ile öznitelik kopyalarından kaçınmak
- 28. Varsayılan Değerlerde Falsy Değerleri Atayarak Tuzaklardan Kaçınmak?
- 29. , cRTP bir şablon içinde kullanıldığı zaman, tür bağımlı şablon adı
- 30. LCD ekrandan fotoğraf çekildikten sonra şeritlerden kaçınmak
Merhaba, tüm cevaplarınız için teşekkürler. CRTP'nin mekaniğini anlıyorum. Bununla birlikte, problem gerçekten polimorfizm olmamasıdır, yani X: base {} ve Y: base {} ise X & Y ilişkisiz türleridir. yani onları aynı kapta tutamam ya da türetilmiş türden haberi olmadan kullanamıyorum. –
Bu _is_ polimorfizmi, beit statik - CRTP'ye giderken, aynı zamanda (statik olarak) polimorf olan templatized istemci kodu da oluşturacaksınız: başka bir türle çalışması için bir kod baytını değiştirmeniz gerekmez. – xtofl