2015-08-11 11 views
6

Qualcuno può, per favore, abbatterlo per me? Conosco le macro e conosco abbastanza bene i modelli, ma non ho idea di ciò che l'autore sta esprimendo con questo. Qual è l'uso previsto, perché è scritto in questo modo? Cosa stiamo definendo per essere cosa qui? Come e perché si usa questo?Cosa significa questa macro modello C++?

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

E ho anche qualcosa come

MY_CLASS()::my_class_impl(int arg_id) 

E vedo anche

template<typename Derived> 
class my_class_impl 

ho sentito da un collega che questo è un caso di CRTP (curiosamente motivo template ricorrenti), ma non ha avuto approfondimenti specifici.

Inoltre, lo vedo utilizzato in seguito come segue:

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

Così, la macro viene utilizzata per firme metodo sostitutivo per la classe my_class_impl quando in realtà loro attuazione?

+2

Che cos'è 'my_class_impl'? – Caninonos

+0

Si prega di consultare la modifica. –

+0

Il 'typename Derived' lo fa apparire come un CRTP purè all'interno di una macro. Quali argomenti ragionevoli potrebbero essere forniti per 'RET_TYPE' e' ... ', e perché la macro è chiamata senza, non lo so. – Quentin

risposta

10

È utilizzato per definire le funzioni membro di my_class_impl<Derived>.

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

espande in:

template <typename Derived> 
void my_class_impl<Derived>::member(Bar b) {} 

Gli argomenti macro variadic può essere utilizzato per vari (standard o meno) attributi, come __declspec(...), [[...]], ecc Ad esempio:

MY_CLASS(void, __declspec(dllexport))::foo(); 

Si espande a:

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

Il MY_CLASS()::my_class_impl(int arg_id), grazie ad un'estensione compilatore che permette mancante parametri macro (presenti su MSVC, nonché Clang e GCC, ero sbagliata), si espande a un costruttore:

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

è anche abbastanza un macro brutto. Non solo è difficile da capire, ma nasconde cose molto banali e si interrompe se provi a restituire un tipo contenente una virgola (std::map<int, int>).

+0

Grazie mille, questo ha senso. Un altro dettaglio, cosa succede se _VA_ARGS_ rappresenta effettivamente un paio di argomenti extra? Come verrà quindi espansa la firma del metodo? Per favore, può fornire un esempio concreto? –

+0

@BaronYugovich ha aggiunto l'esempio. – Quentin

+0

Grazie mille. –

2

Il RET_TYPE è un suggerimento che questa è una funzione e MY_CLASS in particolare suggerimenti per le funzioni membro. Questi possono essere dichiarati anche static.

Meno comune sarebbe [[noreturn]] o [[deprecated]] che sono attributi C++ 14.

La parte <Derived> è piuttosto irrilevante, i modelli di classe possono avere funzioni membro esattamente come le classi possono.

+0

Beh, sì, questo è C++ 14. –