2017-02-02 5 views
1

Является ли приведенная ниже функция примера безопасной с точки зрения вызывающего?Является ли std :: array безопасно возвращенным

std::array<T, SIZE> foo() { 
    std::array<T, SIZE> bar; 
    // Initialization of bar members... 
    return bar; 
} 

Я знаю, что встроенные массивы не безопасно возвратные, но я не уверен, если std::array благополучно возвращается. Если да, то как это достигается?

+0

Подобно тому, как небольшая заметка, 'станд :: array' использует RAII или другое копирование, удаление, ... не будет так гладко, как сейчас :) – Rakete1111

+0

@rici RVO не позаботится о копировании. Во всяком случае, это ускорит копирование ... – rubenvb

+0

«* Я знаю, что встроенные массивы не возвращаются безопасно *« Они не могут быть возвращены вообще. – juanchopanza

ответ

4

Это прекрасно. Возвращение bar от foo() делает копию.

std::array - это структура, имеющая элемент массива. Когда такая структура копируется, массив также копируется. Другими словами, правила различаются для голых массивов и массивов, содержащихся в структурах.

+0

Имеет смысл, не смог найти ответ по поисковому запросу и хотел проверить здравый смысл, спасибо – asimes

0

Это нормально, но это может быть медленным.

C++ 17 представляет гарантированное копирование, но NRVO не входит в комплект.

1

Как упоминалось @Brian std::array - это структура, содержащая элемент массива. Что-то вроде этого:

template<typename T, std::size_t N> 
struct my_array { 
    T array[N]; 
}; 

Обратите внимание, что при копировании my_array, его array является глубоко скопирована. Поэтому возвращение таких структур из функции, которая делает копию временного объекта, никогда не вызовет проблем. Таким образом, с или без наличия RVO, он всегда гарантирует, что проблем не будет.

my_array<int, 5> foo = {1, 2, 3, 4, 5}; 
my_array<int, 5> bar; 

// Copy assignment here 
bar = foo; 

// Change bar's first element 
bar.array[0] = 12; 

// Print foo 
std::copy(std::begin(foo.array), 
      std::end(foo.array), 
      std::ostream_iterator<int>(std::cout, ", ")); 

Результат:

1, 2, 3, 4, 5, 
+0

Вопрос был о том, почему локальный контейнер в стеке безопасно возвращается вызывающему абоненту – asimes

+0

@asimes Ok. Я удалил ненужные части. –