Sto cercando di creare una cosa simile alla tupla, ma ho incontrato un problema per scrivere il mio costruttore.Come creare un costruttore di inoltro perfetto per una classe variadica simile a una tupla
Ecco il codice:
#include <tuple>
template <typename... Ts>
struct B {
template <typename... ArgTypes>
explicit B(ArgTypes&&... args)
{
static_assert(sizeof...(Ts) == sizeof...(ArgTypes),
"Number of arguments does not match.");
}
};
struct MyType {
MyType() = delete;
MyType(int x, const char* y) {}
};
int main()
{
B <int, char> a{2, 'c'}; // works
B <int, bool, MyType, char> b{2, false, {4, "blub"}, 'c'}; // fails
std::tuple<int, bool, MyType, char> t{2, false, {4, "blub"}, 'c'}; // works
}
Ora, questo funziona bene se passare tipi semplici come inizializzatori, ma non lo fa, se provo a passare gli argomenti in una lista di inizializzazione brace-chiusa per non banale oggetto.
GCC-4.7 emette il seguente:
vararg_constr.cpp:21:67: error: no matching function for call to 'B<int, bool, MyType, char>::B(<brace-enclosed initializer list>)'
vararg_constr.cpp:21:67: note: candidates are:
vararg_constr.cpp:6:14: note: B<Ts>::B(ArgTypes&& ...) [with ArgTypes = {}; Ts = {int, bool, MyType, char}]
vararg_constr.cpp:6:14: note: candidate expects 0 arguments, 4 provided
Clang-3.1 il seguente:
vararg_constr.cpp:21:40: error: no matching constructor for initialization of
'B<int, bool, MyType, char>'
B <int, bool, MyType, char> b{2, false,{4, "blub"}, 'c'}; // fails
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
vararg_constr.cpp:6:14: note: candidate constructor not viable: requires 2
arguments, but 4 were provided
explicit B(ArgTypes&&... args)
Ok, ora ciò che mi rende molto, molto curioso è che funziona per tupla! Secondo lo Standard (20.4.2.1) ha un costruttore, che assomiglia molto al mio.
template <class... Types>
class tuple {
public:
// ...
template <class... UTypes>
explicit tuple(UTypes&&...);
// ...
};
Quando si costruisce l'oggetto tupla allo stesso modo, funziona!
Ora vorrei sapere:
A) Che diavolo? Perché std :: tuple è così speciale, e perché i compilatori non deducono il numero corretto di argomenti?
B) Come posso fare questo lavoro?
A) Come fa il compilatore a sapere per il costruttore tupla che si tratta di una tupla e non di MyType? B) Scusa, avrei dovuto elaborare una tupla un po '. Tuple è parametrizzato su Ts ..., ma il costruttore di cui sto parlando è inoltre parametrizzato su UTypes .... –
Ho modificato per rendere il problema A) un po 'più chiaro – ipc
Si noti che per la parte A, ponendo '&&' sui parametri del modello che racchiude il significato, quindi non è più l'inoltro perfetto, ma lo farà (escludendo gli argomenti di riferimento a ' Ts') formano riferimenti di valore, che non sono desiderati. Per la parte B, i riferimenti rvalue sono "corretti" su lvalue 'const &', quindi di solito funziona, ma non è ancora l'inoltro perfetto. – Potatoswatter