Di seguito è un programma che dimostra completamente il problema che sto vedendo.C++ 14 auto lambda può accettare Obj <std :: tuple <void>> - ma le funzioni modello non possono?
Per prima cosa, comincio con un oggetto che viene definito utilizzando un raggruppamento di altri tipi, ho iniziato a utilizzare una std :: tupla <> per gestire il raggruppamento.
template <typename> class object;
template <typename... Rs> class object<std::tuple<Rs...> > {
};
Sono intendendo questi oggetti per essere in grado di avere il tipo void
sparsi nel "pacchetto". Sono già a conoscenza di essere in grado di "istanziare" una tupla di questo tipo (vedi Void type in std::tuple)
voglio passare questi oggetti intorno, forse copiare/spostarli ... nessuno dei loro membri di dati sono un tupla di questi tipi. In effetti, posso riprodurre il problema utilizzando la definizione di oggetto vuoto sopra.
io posso farlo funzionare, utilizzando qualcosa di simile:
template <typename... Rs> struct TGrp {};
template <typename> class object;
template <typename... Rs> class object<TGrp<Rs...> > {
};
Questi tipi di "raggruppamento" le strutture sono utilizzate in frequenly ricorsione variadic, e hanno lo scopo di ottenere mai creato/usato. Solo per raggruppare gli argomenti del modello.
Tuttavia, "voglio" che la firma dell'oggetto sia composta da tipi/nomi "utente previsti".
Fondamentalmente, stavo sperimentando con ogni possibile modo di passare uno di questi oggetti intorno a quando std::tuple
è usato per "gruppo", e potrebbe trovare solo in un modo: auto lambda.
Qualcuno può spiegare:
perché del lambda "auto" può lavorare per questo?
qualcosa sulla deduzione del modello ritardata? come il diff b/w "auto" e "decltype (auto)"?
come "progettare" un parametro di funzione per accettare uno di questi oggetti.
- grazie a tutti voi per eventuali approfondimenti su questa stranezza
Esempio:
#include <tuple>
#include <iostream>
#define GRP std::tuple // IF 'tuple' used: compile error where noted below
//#define GRP TGrp // if THIS is used: all works, and TGrp() is never constructed
// Grouping mechanism
template <typename... Ts> struct TGrp {
TGrp() {
std::cout << "Never printed message\n";
}
};
// MAIN OBJECT (empty for forum question)
template <typename> class object;
template <typename... Rs> class object<GRP<Rs...> > {
};
// Regular function (does NOT work)
void takeobj(object<GRP<void> >& obj) { (void)obj; }
// Lambda - taking anything... (only thing I could make WORK)
auto takeobj_lambda = [](auto obj) { (void)obj; };
// Template func - taking anything (does NOT work)
template <typename T> void takeobj_templ_norm(T obj) { (void)obj; }
template <typename T> void takeobj_templ_clref(const T& obj) { (void)obj; }
template <typename T> void takeobj_templ_lref(T& obj) { (void)obj; }
template <typename T> void takeobj_templ_rref(T&& obj) { (void)obj; }
int main()
{
object<GRP<void> > oval;
//takeobj(oval); // <-- causes compile error
takeobj_lambda(oval); // works
//takeobj_templ_norm(oval); // <-- also error
//takeobj_templ_clref(oval); // <-- also error
//takeobj_templ_lref(oval); // <-- also error
//takeobj_templ_rref(oval); // <-- also error
return 0;
}
Edit: l'aggiunta di un assettato giù riproduzione:
#include <tuple>
// MAIN OBJECT (empty for forum question)
template <typename> class object;
template <typename... Rs> class object<std::tuple<Rs...> > {
};
// Regular function (does NOT work)
void takeobj(object<std::tuple<void> >& obj) { (void)obj; }
// Lambda - taking anything... (only thing I could make WORK)
auto takeobj_lambda = [](auto obj) { (void)obj; };
int main()
{
object<std::tuple<void> > oval;
//takeobj(oval); // <-- causes compile error
takeobj_lambda(oval); // works
return 0;
}
[Codice più semplice da riprodurre] (http://goo.gl/i1xlK6) –
@ M.M Sono nuovo a postare qui e ho pensato che stavi chiedendo un campione migliore ... quindi ho fatto clic sul collegamento. Bella pagina interattiva E sì, quell'esempio più breve è quello che sto vedendo. – CrashNeb
Inoltre: sto utilizzando Visual Studio 2015, quindi utilizzando la pagina di M.M sono riuscito a vedere i messaggi di errore "migliori" di Clang. ;) Tuttavia, perché i modelli di classe lambda (generati internamente) gestiscono questo e i modelli "creati dall'utente" non possono? – CrashNeb