2015-08-26 11 views
9

È facile creare un metodo/funzione parametrizzata sul tipo di una struttura senza nome. È anche facile ottenere il tipo dopo la definizione della struttura.Come estrarre il tipo di una struttura senza nome per creare un nuovo tipo all'interno della struttura stessa?

struct Foo { 
    template <typename T> Foo(T*) { /* we have access to T here */ } 
} 
template <typename T> void baz(T*) { /* we have access to T here */ } 

template<typename T> struct Bar { 
    /* we have access to T here */ 
}; 

void test() { 
    struct { 
    Foo foo { this }; // access in a constructor 
    void test() { baz(this); } // access in a function 
    } unnamed; 
    Bar<decltype(unnamed)> bar; // access after definition 
} 

Ma c'è qualche "magia" che potrebbe consentire l'uso di tipo unnamed s' alla portata struct, o in un metodo statico - non solo all'interno del suo costruttore/metodo di istanza o dopo un'istanza viene dichiarata? E 'banale quando la struct è chiamato:

// How to make it work with S absent (an unnamed struct) ? 
struct S { 
    Bar<S> foo; // how to get our type in an unnamed struct? 
    static void wrapper(void * instance) { 
    static_cast<S*>(instance)->method(); // how to get our type in an unnamed struct? 
    } 
    void method() { ... } 
} would_be_unnamed; 

Questa domanda è stata motivata da un question about how to implement a destructor in an unnamed struct. La soluzione banale che c'era da avvolgere una struttura di nome in un anonimo uno - come involucro può quindi essere utilizzato nelle macro senza scontrarsi con altri tipi, ecc

struct { struct S { ... } s; } unnamed; 

Risolvere l'enigma tipo di accesso consentirebbe una soluzione diversa per la domanda motivante.

+1

Perché non gli dai un nome? Se c'è un problema con l'ambito (ad esempio quando si utilizza una macro), è possibile racchiuderlo in un lambda, '[] {struct NAME {...}; return NAME(); }() '? – dyp

+0

@dyp Non è alla ricerca di una soluzione a un problema pratico - o, piuttosto, il problema pratico (quello di mettere costruttori/distruttori in una struttura senza nome) ha una soluzione semplice ed elegante (una classe nidificata) che non ha bisogno questo problema da risolvere. Mi sto solo chiedendo se c'è un modo per farlo, tutto qui. –

+2

Correlati: [Posso implementare un tipo di membro autonomo 'self' in C++?] (Http://stackoverflow.com/q/21143835/) – dyp

risposta

3

Qualcosa come questo, forse?

L'idea è che in realtà ci siano due strutture senza nome. Innanzitutto, unnamed contiene tutto il codice/i dati effettivi e tutto il resto. Quindi c'è unnamedWrapper che, essendo in grado di utilizzare decltype su unnamed, è solo un wrapper completamente inoltro (anche per costruttori!) Intorno a unnamed, con la singola specialità che esporta il tipo unnamed attraverso un typedef.

#include <cstddef> 

template<typename T> 
size_t templatedSizeof() { 
    return sizeof(T); 
} 

struct { 
    char something; 
    short somethingElse; 
    int  moreGargabe; 
    long evenMoreUselessGarbage; 
} unnamed; 

struct : public decltype(unnamed) { 
    typedef decltype(unnamed) TheType; 

    using TheType::TheType; // Use same constructors 
} unnamedWrapper; 
+0

La domanda ha due esempi alla fine che mi piacerebbe lavorare. Mi piacerebbe essere in grado di avere un typedef all'interno della struct senza nome, o (equivalentemente) un tipo all'interno di un metodo statico, che finisce con il tipo di struct. –

+0

Questa è ovviamente una soluzione. Mi chiedo se sia possibile farlo senza il secondo involucro. –

+0

@KubaOber: cercherò di trovare un'altra soluzione e postare un altro commento/modificare la risposta se ne trovo una. – 3442

Problemi correlati