Sono i costruttori dovrebbero variadic per nascondere quelle implicitamente generate?
-
22-10-2019 - |
Domanda
sono costruttori variadic suppone per nascondere quelli implicitamente generati, vale a dire il costruttore di default e il costruttore di copia?
struct Foo
{
template<typename... Args> Foo(Args&&... x)
{
std::cout << "inside the variadic constructor\n";
}
};
int main()
{
Foo a;
Foo b(a);
}
In qualche modo mi aspettavo questo per stampare nulla dopo aver letto questa risposta , ma esso stampa inside the variadic constructor
due volte sul g ++ 4.5.0 :( è questo comportamento corretto?
Succede anche senza modelli variadic:
struct Foo
{
Foo()
{
std::cout << "inside the nullary constructor\n";
}
template<typename A> Foo(A&& x)
{
std::cout << "inside the unary constructor\n";
}
};
int main()
{
Foo a;
Foo b(a);
}
Ancora una volta, entrambe le linee vengono stampate.
Soluzione
Dichiarazione del costruttore di copia implicitamente dichiarato non è, infatti, essere soppresso. E 'solo che non viene chiamato a causa delle regole di risoluzione di sovraccarico.
Il costruttore di copia implicitamente dichiarato ha la forma Foo(const Foo&)
. La parte importante di questo è che ci vuole un riferimento const. Il modello costruttore accetta un riferimento non-const.
a
non è const, quindi il modello costruttore dall'utente dichiarato non-const è preferibile rispetto il costruttore di copia implicitamente dichiarata. Per chiamare il costruttore di copia implicitamente dichiarata, è possibile effettuare a
const:
const Foo a;
Foo b(a);
oppure è possibile utilizzare static_cast
per ottenere un riferimento const a a
:
Foo a;
Foo b(static_cast<const Foo&>(a));
Le regole di risoluzione di sovraccarico che descrivono questo si trovano per lo più in §13.3.3.2 / 3 del C ++ 0x FCD. Questo scenario particolare, con una combinazione di Ivalue e riferimenti rvalue, è specie descritta dai vari esempi a pagina 303.
Un variadic costruttore modello sopprimerà il costruttore di default implicitamente dichiarata a causa di un modello costruttore variadic è user-dichiarato e il costruttore di default implicitamente dichiarato è previsto solo se non ci sono costruttori dall'utente dichiarato (C ++ 0x FCD §12.1 / 5 ):
Se non c'è nessun costruttore di user-dichiarata per la classe
X
, un costruttore non avendo parametri è implicitamente dichiarato come default.
Un variadic costruttore template non sopprimerà il costruttore di copia implicitamente dichiarato perché solo un costruttore non può essere modello di un costruttore di copia (C ++ 0x FCD §12.8 / 2, 3, e 8):
Un costruttore non template per la classe
X
è un costruttore di copia se il suo primo parametro è di tipoX&
,const X&
,volatile X&
oconst volatile X&
, e uno non ci sono altri parametri o altro tutti gli altri parametri hanno argomenti di default.Un costruttore non template per la classe
X
è un costruttore mossa se il suo primo parametro è di tipoX&&
,const X&&
,volatile X&&
oconst volatile X&&
, e uno non ci sono altri parametri o altro tutti gli altri parametri hanno argomenti di default.Se la classe de fi nizione non dichiara esplicitamente un costruttore di copia e non v'è nessun costruttore mossa dall'utente dichiarato, un costruttore di copia viene implicitamente dichiarato come default.