2013-08-07 3 views
20

Перемещение не может быть эффективно реализовано (O (1)) на std :: array, поэтому почему он имеет конструктор перемещения?Должен ли std :: array иметь конструктор перемещения?

+8

'std :: array' не имеет * any * конструкторов, кроме значений по умолчанию, сгенерированных компилятором. – Casey

+1

Откуда у вас эта неправильная информация (что 'std :: array' имеет конструктор перемещения)? –

+1

@ R.MartinhoFernandes созданный компилятором конструктор перемещения. – Walter

ответ

28

std::array имеет созданный компилятором конструктор перемещения, который позволяет перемещать все элементы одного экземпляра в другой. Это удобно, если элементы эффективно движимые или, если они только движимые:

#include <array> 
#include <iostream> 

struct Foo 
{ 
    Foo()=default; 
    Foo(Foo&&) 
    { 
    std::cout << "Foo(Foo&&)\n"; 
    } 
    Foo& operator=(Foo&&) 
    { 
    std::cout << "operator=(Foo&&)\n"; 
    return *this; 
    } 
}; 

int main() 
{ 
    std::array<Foo, 10> a; 
    std::array<Foo, 10> b = std::move(a); 
} 

Так что я бы сказал, std::array должен иметь конструктор шаг копирования, специально, так как он поставляется бесплатно. Не нужно требовать, чтобы он был активно отключен, и я не вижу в этом никакой пользы.

+0

Требуется ли, чтобы конструктор перемещения элемента был 'nothrow'? Или он может просто покинуть операцию в любом законном состоянии? –

+1

@MarkB хороший вопрос, я не думал об этом. Этот код работает так же, как и на gcc 4.7.3, даже если я добавлю конструктор копирования. Я должен буду прочитать стандарт, но я предполагаю, что переход от одного контейнера к другому не может ожидать поддержки надежной гарантии исключения. – juanchopanza

+0

@juanchopanza: Я считаю, что вы правы в гарантии безопасности исключений. То есть, 'std :: array' move-constructor не обеспечивает надежную гарантию безопасности исключений. Только основной. См. Первую марку 12.8/15. Мое единственное сомнение заключается в том, что «соответствующий подобъект» также является значением r. Как вы думаете? –

0

Посмотри на стандарте: конструкторы

23.3.2.2 массива, копирование и присваивание [array.cons]

Условий для агрегата (8.5.1), должны быть выполнены. Класс array опирается на неявно объявленные специальные функции-члены (12.1, 12.4 и 12.8), чтобы соответствовать таблице требований к контейнеру в 23.2. В дополнение к требованиям, указанным в таблице требований к контейнеру, оператор неявного перемещения и назначение перемещения оператора для массива требуют, чтобы T был MoveConstructible или MoveAssignable, соответственно.

Конструктор перемещения и оператор присваивания, безусловно, не являются бесплатными, они не могут быть предоставлены.

23

Суммируя и расширить другие ответы, array<T> должны быть подвижны (когда T сам подвижны), потому что:

  • T может быть эффективно подвижны.
  • T может быть перемещение только.
+0

LOL, это ничего не говорит. «должен» «может» «может» ... по крайней мере, вы имеете в виду «должно» по стандарту? –

+0

@ v.oddou Это говорит о том, почему факт, что 'array ' ** является ** движимым (для подвижного T) имеет смысл. – juanchopanza

+0

@juanchopanza: это всего лишь письмо к Санта-Клаусу. это было уже очевидно до вопроса. да, мы хотим, что сказано. теперь мы хотим узнать ** факты ** о том, есть это или нет, и почему. –

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