I bawił się z wyraźnymi konstruktorów i ich zachowanie, więc stworzyłem tę klasę:Dlaczego nie mogę używać wyraźny konstruktora do skonstruowania typ zwracany
#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";
}
};
który jest w zasadzie tylko zalążek aby przetestować jawne konstruktorzy. Potem chciałem wypróbować kilka sytuacji. Więc próbowałem to:
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()};
}
I jak widać nie mogę wrócić a
wewnątrz foo()
. Wiem, że próbuje zainicjować typ zwrotu Foo
z konstruktorem kopiującym, ale z jakiegoś powodu nie może go użyć.
Jak to możliwe, że nie można użyć mojego dostarczonego konstruktora kopii? Wiem, że specyfikacja explicit
powoduje problem, ponieważ po usunięciu go z konstruktora kopiowania działa. Ale dlaczego?
Co myli mnie jeszcze bardziej to, że mogę wykonać następujące czynności:
void bar(const X& a) { /* */ }
bar(X{});
Nie narzekam. Ale czy nie powinien on konstruować jego parametru a
w ten sam sposób, w jaki konstruuje swój typ zwracania?
Wywołanie 'bar' nie wywołuje w ogóle konstruktora, po prostu przekazuje referencję (wskaźnik). powinieneś zobaczyć wywołania no copy konstruktorów. –