Vedere Should I use() or {} when forwarding arguments?. foo
è un clone std::vector
.Perché non esistono std :: initializer_list overload per std :: make_unique et al?
In N4140, unique.ptr.createstd::make_unique
è specificato come così:
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
Commento: Questa funzione non partecipa risoluzione sovraccarico meno
T
non è un array.Resi:
unique_ptr<T>(new T(std::forward<Args>(args)...))
.
Ciò significa implementazioni sono obbligati a ricorrere ()
anziché {}
inizializzare oggetti. Come esempio, la seguente
auto s1 = std::make_unique<foo>(3, 1).get()->size();
auto s2 = std::make_unique<foo>(1).get()->size();
auto s3 = std::make_unique<foo>(2).get()->size();
std::cout << s1 << s2 << s3;
uscite 312
mentre se {}
(all'interno std::make_unique
) è stato utilizzato 211
sarebbe uscita. Poiché gli elenchi di inizializzazione non possono essere dedotti, è necessario passare esplicitamente il std::initializer_list
per ottenere il risultato finale. La domanda è, perché non è un sovraccarico come questo fornito?
namespace test
{
template <class T, class Deduce>
std::unique_ptr<T> make_unique(std::initializer_list<Deduce> li)
{
return ::std::make_unique<T>(li);
}
};
int main()
{
auto p1 = test::make_unique<foo>({3, 1}).get()->size();
auto p2 = test::make_unique<foo>({1}).get()->size();
auto p3 = test::make_unique<foo>({2}).get()->size();
std::cout << p1 << p2 << p3;
}
Uscite 211
.
Non considero i motivi per cui "è possibile scrivere da soli" o "per evitare il rigonfiamento dello standard". C'è qualche svantaggio nel fornire questo sovraccarico?
Non credo SFINAE è necessario. 'make_unique> (1, 73);' funziona perfettamente bene se lo tolgo dal namespace e faccio 'using namespace std;' (per assicurarsi che entrambi gli overload siano visibili). Se qualcuno fa "make_unique > ({1, 73});" è colpa loro. –
user6319825
@ user6319825.Sì, SFINAE non è essenziale, la compilazione fallisce in entrambi i casi, solo nella mia esperienza i messaggi di errore in un ambiente SFINAE sono "più facili" da diagnosticare. – Niall
Ancora. Hanno deliberato di dire "nuovo T (std :: forward (args) ...)" invece di lasciarlo all'implementazione come per [opzionale] (http://eel.is/c++draft/optional.object .ctor # 23): "Inizializza il valore contenuto come se direct-non-list-inizializzando un oggetto di tipo' T' con gli argomenti 'std :: forward (args)' .... "Questo mi fa pensare che ci sia qualche discussione * da qualche parte * almeno per 'make_unique' in particolare. –
user6319825