Ho suonato in giro con i costruttori espliciti ed il loro comportamento, così ho creato questa classe:Come mai non riesco a usare costruttore esplicito per la costruzione di un tipo di ritorno
#include <iostream>
class X
{
public:
explicit X(void)
{
std::cout << "Default constructor\n";
}
explicit X(X const& x)
{
std::cout << "Copy constructor\n";
}
explicit X(X&& x)
{
std::cout << "Move constructor\n";
}
};
che è fondamentalmente solo uno stub per mettere alla prova esplicita costruttori. Poi ho voluto provare diverse situazioni. Così ho provato questo:
X foo(void)
{
X a{};
return a; // ERROR: no matching constructor found!
}
int main()
{
X w{}; // Default Constructor
X x{w}; // Copy Constructor
X y{std::move(x)}; // Move Constructor
X z{foo()};
}
E come potete vedere non posso tornare a
all'interno foo()
. So che tenta di inizializzare il tipo di ritorno Foo
con il costruttore di copie, ma per qualche motivo non può usarlo.
Come mai non è possibile utilizzare il mio costruttore di copie fornito? So che la specifica explicit
causa il problema, perché quando la rimuovo dal costruttore di copie funziona. Ma perché?
Ciò che mi confonde ancora di più è che posso effettuare le seguenti operazioni:
void bar(const X& a) { /* */ }
bar(X{});
E non si lamenta. Ma non dovrebbe bar()
costruire il suo parametro a
allo stesso modo foo()
costruisce il suo tipo di ritorno?
chiamare 'bar' non chiama il costruttore, basta passare il riferimento (puntatore). dovresti vedere che i costruttori non copia sono chiamati. –