Следующий код компилируется с помощью clang 3.0 / libc ++:
#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;
}
Но это не так (std::string
параметр добавлен):
#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 жалуется на использование удаленного конструктора. Для меня это не имеет смысла, поскольку std::make_shared
не должен копировать экземпляр Foo, единственное, что вызовет вызов (удаленный) конструктор копирования std::unique_ptr
.
Но, о чудо, как только я определю конструктор перемещения явно, он скомпилируется.
#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;
}
Теперь вопросы:
- Почему он компилируется в первом примере, а не во втором?
- Может ли
std::make_shared
копировать / перемещать объект при его создании?
- Почему добавление конструктора перемещения решает проблему? Я не помню, чтобы добавление конструктора не по умолчанию должно подавлять неявный конструктор перемещения.
РЕДАКТИРОВАТЬ: Проверено, и все примеры, как представляется, прекрасно компилируются с gcc 4.5.1 (через ideone.com), я подозреваю, что это ошибка clang / libc ++, но вопросы 2 и 3 все еще остаются Кроме того, я хотел бы знать, какой компилятор более «правильный».