ho intenzione di usare shared_ptr
un bel po 'in un progetto imminente, quindi (non essere a conoscenza di std::make_shared
) Volevo scrivere una funzione template variadic spnew<T>(...)
come shared_ptr
-returning stand-in per new
. Tutto è andato liscio fino a quando ho tentato di utilizzare un tipo il cui costruttore include uno initializer_list
. Ottengo il seguente da GCC 4.5.2, quando provo a compilare l'esempio minimo di seguito:Espansione parametro confezione contenente initializer_list al costruttore
In function 'int main(int, char**)': too many arguments to function 'std::shared_ptr spnew(Args ...) [with T = Example, Args = {}]' In function 'std::shared_ptr spnew(Args ...) [with T = Example, Args = {}]': no matching function for call to 'Example::Example()'
Stranamente, ottengo errori equivalenti se sostituisco std::make_shared
per spnew
. In entrambi i casi, sembra che i parametri vengano dedotti erroneamente quando è coinvolto un initializer_list
, trattando erroneamente Args...
come vuoto. Ecco l'esempio:
#include <memory>
#include <string>
#include <vector>
struct Example {
// This constructor plays nice.
Example(const char* t, const char* c) :
title(t), contents(1, c) {}
// This one does not.
Example(const char* t, std::initializer_list<const char*> c) :
title(t), contents(c.begin(), c.end()) {}
std::string title;
std::vector<std::string> contents;
};
// This ought to be trivial.
template<class T, class... Args>
std::shared_ptr<T> spnew(Args... args) {
return std::shared_ptr<T>(new T(args...));
}
// And here are the test cases, which don't interfere with one another.
int main(int argc, char** argv) {
auto succeeds = spnew<Example>("foo", "bar");
auto fails = spnew<Example>("foo", {"bar"});
}
Questa è solo una svista da parte mia o un bug?
C'è 'std :: make_shared', a proposito. – GManNickG
@GMan: Sì, l'ho trovato e lo userò, ma sono ancora curioso di sapere cosa succede con ciò che ho scritto. –
@GMan: In realtà, vieni a provare a sostituire 'make_shared' per' spnew' nel mio esempio, non riesce ancora per il caso 'fallisce' con errori equivalenti. Quindi ora almeno so dove l'errore non è ... –