Sto sperimentando le nuove funzionalità di C++ 11. Nella mia configurazione mi piacerebbe molto usare i costruttori ereditari, ma sfortunatamente nessun compilatore implementa ancora quelli. Pertanto sto cercando di simulare lo stesso comportamento. Posso scrivere qualcosa di simile:rilevamento di costruttori protetti di classe (possibilmente astratta)
template <class T>
class Wrapper : public T {
public:
template <typename... As>
Wrapper(As && ... as) : T { std::forward<As>(as)... } { }
// ... nice additions to T ...
};
Questo funziona ... la maggior parte del tempo. A volte il codice che utilizza le classi Wrapper
deve utilizzare SFINAE per rilevare come è possibile costruire tale tipo di Wrapper<T>
. Esiste tuttavia il seguente problema: per quanto riguarda la risoluzione del sovraccarico, il costruttore di Wrapper<T>
accetta qualsiasi argomento, ma la compilazione non riesce (e questo è non coperto da SFINAE) se il tipo T
non può essere costruito utilizzando quelli.
stavo cercando di attivare in modo condizionale le diverse istanze del modello costruttore utilizzando enable_if
template <typename... As, typename std::enable_if<std::is_constructible<T, As && ...>::value, int>::type = 0>
Wrapper(As && ... as) // ...
che funziona bene fino a quando:
- il costruttore appropriato di
T
èpublic
T
non è astratto
La mia domanda è: come sbarazzarsi dei due precedenti vincoli?
ho cercato di superare il primo controllando (utilizzando SFINAE e sizeof()
) se l'espressione new T(std::declval<As &&>()...)
è ben formata all'internoWrapper<T>
. Ma questo, ovviamente, non funziona, perché l'unico modo in cui una classe derivata può utilizzare il costruttore protetto della sua base è nell'elenco di inizializzazione dei membri.
Per il secondo, non ho la minima idea - ed è quello che ho bisogno di più, perché a volte è la Wrapper
che implementa le funzioni astratte di T
, rendendolo un tipo completo.
Voglio una soluzione che:...
- è corretto secondo le normali
- opere in nessuno dei gcc-4.6 *, gcc-4.7 * o clang-3 *
Grazie!
Sono di fretta, ma forse http://stackoverflow.com/questions/8984013/can-sfinae-detect-private-access-violations possono essere d'aiuto in questo caso, non mi piacerebbe contare su gcc 4.6 per farlo bene anche se – PlasmaHH
il controllo degli accessi è un po 'complicato qui: se usi 'sizeof()', il compilatore controllerà l'intera espressione, accesso incluso - ma poi l'accesso è controllato ** dal contesto dell'espressione **, che fallisce nel caso di costruttori protetti; tutto tranne "sizeof" funziona solo a livello di risoluzione del sovraccarico e di inferenza del tipo, quindi le violazioni di accesso non attiveranno SFINAE - ma poi, non vedo alcun modo di fare qualcosa con un costruttore, dato che non può essere passato come argomento modello . Per quanto riguarda il supporto del compilatore, sarò felice se ** qualsiasi ** di quanto sopra accetti il codice. –