2015-08-11 28 views
6

Birisi lütfen bunu benim için yıkabilir misiniz? Makroları biliyorum ve şablonlarla oldukça tanıdık ama yazarın bununla ne ifade ettiğini bilmiyorum. Amaçlanan kullanım nedir, neden böyle yazılmıştır? Burada ne olmak istiyoruz? Bunu neden ve nasıl kullanır?Bu C++ şablon makrosu ne anlama geliyor?

#define MY_CLASS(RET_TYPE, ...)\ 
    template<typename Derived>\ 
    __VA_ARGS__\ 
    RET_TYPE my_class_impl<Derived> 

Ve ayrıca bu cRTP vakası (merakla yinelenen şablon desen) olduğu bir meslektaşım duyduğumuz

template<typename Derived> 
class my_class_impl 

MY_CLASS()::my_class_impl(int arg_id) 

Ve gibi bir şey olduğunu da görebiliyordum var ama daha spesifik bir anlayışı yoktu. Yani

MY_CLASS(some_type)::find_desired_val(int x) { 
// some code 
} 

, makro sınıfının gerçekten tamamlamadan my_class_impl için yedek bir yöntem imzalar için kullanılır:

Ayrıca, aşağıdaki gibi sonradan kullanılan bakınız?

+2

'my_class_impl' nedir? – Caninonos

+0

Lütfen düzenlemeye bakın. –

+0

Türetme Türetilmiş bir makro içinde püskürtülen bir CRTP gibi görünmesini sağlar. RET_TYPE' ve '...' için ne mantıklı argümanlar sağlanabilir ve neden makro yok deniliyor, bilmiyorum. – Quentin

cevap

10

my_class_impl<Derived>'un üye işlevlerini tanımlamak için kullanılır.

MY_CLASS(void, __declspec(dllexport))::foo(); 
:
template <typename Derived> 
void my_class_impl<Derived>::member(Bar b) {} 

değişkin makro bağımsız değişkenler

vb Örneğin, (standart veya değil) özellikleri gibi __declspec(...), [[...]] çeşitli için kullanılabilir:

MY_CLASS(void)::member(Bar b) {} 

genişler

Genişler:

template <typename Derived> 
__declspec(dllexport) void my_class_impl<Derived>::foo() {} 

MY_CLASS()::my_class_impl(int arg_id), bir kurucusuna, (yanılmışım MSVC yanı sıra Clang ve GCC mevcut) makro parametreleri eksik verir genişleyen bir derleyici uzantısı sayesinde:

template <typename Derived> 
/* nothing */ my_class_impl<Derived>::my_class_impl(int arg_id) {} 

Ayrıca oldukça olduğunu çirkin makro Sadece anlamak zor değil, çok sıradan şeyleri gizler ve herhangi bir virgül (std::map<int, int>) içeren bir tür döndürmeye çalışırsanız kırılır.

+0

Çok teşekkür ederim, bu mantıklı. Bir detay daha, eğer _VA_ARGS_ aslında bir kaç ek argüman için duruyorsa? Yöntem imzası nasıl genişleyecektir? Lütfen somut örnek verebilir misiniz? –

+0

@BaronYugovich örneği ekledi. – Quentin

+0

Çok teşekkür ederim. –

2

RET_TYPE, bunun bir işlev olduğunu ve MY_CLASS özellikle üye işlevlerindeki ipuçlarını gösterir. Bunlar da static olarak bildirilebilir. Daha az yaygın olan, [[noreturn]] ya da C++ 14 öznitelikleri olan [[deprecated]] olacaktır.

<Derived> bölümünün bu konuyla alakası yoktur, sınıf şablonları yalnızca sınıflar gibi üye işlevlerine sahip olabilir.

+0

Eh, evet, bu C++ 14. –