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.

È stato utile?

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 tipo X&, const X&, volatile X& o const 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 tipo X&&, const X&&, volatile X&& o const 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top