2011-12-19 5 views
12

Следующий код компилирует с лязгом 3.0/LibC++:СТД :: make_shared, СТД :: unique_ptr и перемещение Конструкторы

#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; 
} 

Теперь вопросы:

  1. Почему компилировать в первом примере, но не второй?
  2. Can std::make_shared копировать/перемещать объект при его создании?
  3. Почему добавление конструктора перемещения устраняет проблему? Я не помню, что добавление конструктора не по умолчанию должно подавлять неявный конструктор перемещения.

EDIT: Проверено и все примеры, по всей видимости компилироваться с GCC 4.5.1 (через ideone.com), я подозреваю, что это случай ошибки Clang/LibC++, но вопросы 2 и 3 до сих пор стоят, плюс я хотел бы знать, какой компилятор более «правильный».

+1

Я не думаю, что когда-либо неявный конструктор шаг при условии –

+0

@parapura Rajkumar (1) удаление unique_ptr делает его уйти (даже не по умолчанию ctor), (2) неявный механизм перемещения по-прежнему определяется в соответствии с последней редакцией: http: //mmocny.wordpress.com/2010/12/09/implicit-move-wont-go/ –

+0

@parapurarajkumar: действительно, я помню, что читал обсуждения, где неявные конструкторы перемещения были плохими, и их следует удалить из стандарта. Однако я не знаю конца истории. –

ответ

20

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

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

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

Нет, я не верю, что это возможно.

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

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

Update

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

+5

Вау! один час обернуть! Итак, если мы найдем другие ошибки в clang/libC++, мы можем просто отправить их в Stackoverflow, чтобы позорить вас в их исправлении быстро? –

+3

@deft_code: Я думаю, что Говард достаточно стойкий, чтобы исправить ошибки, не стыдясь этого. ; -] – ildjarn

+3

@deft_code: Это похоже на метод эффекта. ;-) –

Смежные вопросы