std :: векторное поведение конструктора - PullRequest
3 голосов
/ 09 октября 2011

Возьмите следующий код:

std::vector<std::vector<int>> v(10, 10);

Этот код не компилируется с libstdc ++. Однако он компилируется с библиотекой Visual Studio C ++. Я ожидал бы, что v заполнен 10 векторами размера 10, и это то, что я получаю с Visual Studio.

Конструктор, вызываемый в Visual Studio, принимает два итератора. Сам конструктор определяется как:

template<class _Iter>
vector(_Iter _First, _Iter _Last)
    : _Mybase()
{   // construct from [_First, _Last)
    _Construct(_First, _Last, _Iter_cat(_First));
}

Существует две версии функции шаблона _Construct. Оба имеют одинаковую сигнатуру, но один инициализирует вектор из диапазона, а другой инициализирует вектор с помощью N копий копии типа значения, созданной из второго параметра. В этом случае параметры шаблона действительны только для второй версии _Construct.

В результате v заполняется 10 копиями вектора, копия которого была построена из значения 10. Такой же путь к коду берется при его построении следующим образом, что вы должны сделать для того же эффекта, используя libstdc ++:

std::vector<int> temp(10);
std::vector<std::vector<int>> v(10, temp);

Какая реализация здесь верна? Это ошибка libstdc ++ или расширение библиотеки Visual Studio C ++?

Редактировать: Просто чтобы уточнить, я не спрашиваю, должен ли он вызывать конструктор диапазона. Я спрашиваю, какая реализация C ++ имеет правильное поведение, независимо от того, какой путь требуется для его достижения.

Ответы [ 2 ]

3 голосов
/ 09 октября 2011
std::vector<std::vector<int>> v(10, 10);

Это не должно компилироваться, потому что конструктор единственного аргумента вектора является явным.

C ++ 03:

explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());

C ++ 11:

explicit vector(size_type n);

Это означает, что число вроде 10 не может неявно превратиться в вектор размером 10.

0 голосов
/ 09 октября 2011

Я ожидал бы, что v заполнится 10 векторами размером 10

Что именно и происходит с GCC / libstdc ++ 4.1.2. _Construct, который называется

void std::_Construct<std::vector<int>, int>(std::vector<int>*, int const&)

(без учета распределителей). Я не могу сказать вам, что стандарт говорит об этом, но я догадываюсь, что это ошибка в более старом GCC / libstdc ++.

...