Poniższy kod kompiluje się z brzękiem 3,0/libC++:std :: make_shared STD :: unique_ptr i przenieść konstruktorzy
#include <memory>
class Foo
{
public:
Foo()
: mem_(new int(10))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>();
return 0;
}
Ale to nie (std::string
parametr dodane):
#include <memory>
#include <string>
class Foo
{
public:
Foo(const std::string& s)
: mem_(new int(10))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>("aaa");
return 0;
}
Clang skarży się na użycie usuniętego konstruktora. Dla mnie to nie ma sensu, ponieważ std::make_shared
nie powinno kopiować instancji Foo, jedynej rzeczy, która wyzwala wywołanie konstruktora kopiowania (usuniętego) z std::unique_ptr
.
Ale zaraz po tym jak zdefiniuję konstruktor ruchu jawnie, kompiluje.
#include <memory>
#include <string>
class Foo
{
public:
Foo(const std::string& s)
: mem_(new int(10))
{
}
Foo(Foo&& other)
: mem_(std::move(other.mem_))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>("aaa");
return 0;
}
Teraz pytania:
- Dlaczego kompilować w pierwszym przykładzie, ale nie drugi?
- Czy można skopiować/przenieść obiekt podczas jego tworzenia?
- Dlaczego dodanie konstruktora ruchu rozwiązuje problem? Nie przypominam sobie, że dodanie innego niż domyślny konstruktora powinno powstrzymać niejawny konstruktor ruchu.
EDIT: sprawdzone i wszystkie przykłady wydają się skompilować grzywny z gcc 4.5.1 (przez ideone.com), podejrzewam, że jest to przypadek Clang/libC++ bug, ale pytania 2 i 3 nadal stoją, plus chciałbym wiedzieć, który kompilator jest bardziej "poprawny".
Nie sądzę, istnieje coraz niejawny konstruktor ruch warunkiem –
@parapura Rajkumar (1) usunięcie unique_ptr sprawia, że odejdzie (nawet z non-default ctor), (2) niejawny konstruktor ruchu jest nadal definiowany zgodnie z najnowszym brzmieniem: http: //mmocny.wordpress.com/2010/12/09/implicit-move-wont-go/ –
@parapurarajkumar: rzeczywiście, przypominam sobie, że czytałem dyskusje, w których niejawni konstruktorzy ruchu byli złymi rzeczami i powinni zostać usunięci ze standardu. Jednak nie znam końca historii. –