Подтвердить что ты не робот

Std:: make_shared, std:: unique_ptr и перемещение конструкторов

Следующий код компилируется с помощью clang 3.0/libС++:

#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/libС++, но вопросы 2 и 3 все еще остаются stand, плюс я хотел бы знать, какой компилятор более "правильный".

4b9b3361

Ответ 1

Почему он компилируется в первом примере, но не во втором?

Это ошибка libС++. Я сейчас работаю над исправлением...

Может ли std:: make_shared копировать/перемещать объект при его создании?

Нет, я не думаю, что это возможно.

Почему добавление конструктора перемещения устраняет проблему? Я не помню что добавление конструктора не по умолчанию должно подавлять неявный ход конструктор.

В версии clang, которую вы используете, неявные конструкторы перемещения еще не реализованы.

Обновление

Исправлено: http://llvm.org/bugs/show_bug.cgi?id=11616