RVO и std :: vector реализации

Я написал код ниже, чтобы проверить, что популярные компиляторы C ++ 03 реализуют RVO, когда это возможно.
(См. Мой связанный вопрос о RVO Оптимизация возвращаемого значения: как я могу избежать копирования больших контейнеров STL.).

Насколько я понимаю, короткий ответ — нет. Но я не уверен, что понимаю.

У меня есть следующие пять вопросов о реализации std :: vector clang gcc и VS9,
прочитайте код и вывод ниже:

  1. Почему компилятор C Fun1 дважды копирует вектор?
  2. Почему компилятор B и C всегда создают хотя бы один незапрошенный элемент?
  3. Почему этот незапрошенный элемент создается дважды с помощью компилятора C Fun2?
  4. Почему резервирование пространства дает еще один незапрошенный элемент для компиляторов B и C?
  5. Соответствует ли все это стандарт?
  6. Бонусный вопрос: все ли это соответствует ожиданиям пользователя?

#include <iostream>
#include <vector>
#include <cassert>

#define SIZE (3)

class NRVO{
public:
NRVO() : name_(-1){}
~NRVO(){
std::cout << "Destroy "<< name_ << "\n";
}
void set_name(){name_ = counter++;}
private:
int name_;
static int counter;
};

int NRVO::counter = 0;

std::vector<NRVO> fun1(){
std::vector<NRVO> vec(SIZE);
for(std::vector<NRVO>::iterator v_it = vec.begin();
v_it != vec.end();
++v_it){
v_it->set_name();
}
return vec;
}

void fun2(std::vector<NRVO>& vec){
vec.clear();
vec.resize(SIZE);
for(std::vector<NRVO>::iterator v_it = vec.begin();
v_it != vec.end();
++v_it){
v_it->set_name();
}
return;
}

int main(){
{
std::vector<NRVO> myNrvo1;
std::cout << "Fun1\n";
myNrvo1 = fun1();
assert(myNrvo1.size()==SIZE);
}
{
std::vector<NRVO> myNrvo2;
std::cout << "Fun2\n";
fun2(myNrvo2);
assert(myNrvo2.size()==SIZE);
}
{
std::vector<NRVO> myNrvo3;
myNrvo3.reserve(SIZE);
std::cout << "Fun3\n";
fun2(myNrvo3);
assert(myNrvo3.size()==SIZE);
}
return 0;
}

Вывод с популярным компилятором C ++ 11 A

Fun1
Destroy 0
Destroy 1
Destroy 2
Fun2
Destroy 3
Destroy 4
Destroy 5
Fun3
Destroy 6
Destroy 7
Destroy 8

Вывод с популярным компилятором C ++ 03 B

Fun1
Destroy -1
Destroy 0
Destroy 1
Destroy 2
Destroy 0
Destroy 1
Destroy 2
Fun2
Destroy -1
Destroy 3
Destroy 4
Destroy 5
Fun3
Destroy -1
Destroy -1
Destroy 6
Destroy 7
Destroy 8

Вывод с популярным компилятором C ++ 03 C

Fun1
Destroy -1
Destroy 0
Destroy 1
Destroy 2
Destroy 0
Destroy 1
Destroy 2
Destroy 0
Destroy 1
Destroy 2
Fun2
Destroy -1
Destroy -1
Destroy 3
Destroy 4
Destroy 5
Fun3
Destroy -1
Destroy -1
Destroy -1
Destroy 6
Destroy 7
Destroy 8

4

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]