stl вектор и c++: как да .resize без конструктор по подразбиране?

Как да кажа на STL, специално за метода resize() във вектор, да инициализира обекти с конструктор, различен от подразбиращия се, и с кои параметри?

Например:

class something {
    int a;
    something (int value);
}

std::vector<something> many_things;

many_things.resize (20);

По-общо, как да принудя STL да използва моя конструктор, когато трябва да създава обекти и да предава параметри на този конструктор?

В моя случай добавянето на конструктор по подразбиране не е опция и бих предпочел да не използвам масив от указатели за решаване на проблема.


person conejoroy    schedule 06.11.2009    source източник


Отговори (4)


Използвайте претоварването с 2 аргумента: many_things.resize(20, something(5));

person MSalters    schedule 06.11.2009

Мога да измисля решение, но предупреждавам, че е доста грозно. Не знам защо не искате да добавите конструктор по подразбиране, но ако просто искате да попречите на потребителите на класа да създават неинициализирани екземпляри, можете просто да направите конструктора по подразбиране частен и да декларирате подходящия векторен клас за приятел:

class Foo {
public:
   Foo( int x ) : num( x ) {}

   int GetX( ) { return num; }
private:
   friend class std::vector< Foo >;

   int num;
   Foo( ) : num( 10 ) {}
};

Това е грозно по няколко причини, най-вече защото работи само за един тип контейнер. Няма друг начин, защото STL контейнерите просто изискват елементите им да могат да се конструират по подразбиране.

person Björn Pollex    schedule 06.11.2009
comment
Открих, че това не работи, защото std::vector<Foo> делегира конструкцията на друг клас и така приятелството става безполезно. Вижте тук - person Matt Clarkson; 17.04.2013
comment
Благодаря за актуализацията! Предполагам, че това е, което получавате в зависимост от подробностите за изпълнението. преди 3,5 години-аз не бях толкова опитен :) - person Björn Pollex; 17.04.2013

Можете да използвате reserve(), за да увеличите размера на буфера и ръчно да добавите (push_back()) необходимите елементи в цикъл.

person sharptooth    schedule 06.11.2009
comment
След това имате явен твърдо кодиран цикъл вместо неявния, използван от resize. - person Matthieu M.; 06.11.2009
comment
използвайте emplace_back (en.cppreference.com/w/cpp/container/vector/emplace_back) може да е по-добър вариант. не копира обекти. - person waytofall; 01.05.2019

С подобна специализация (съжалявам, написах това само с минимални проверки)?

#include <vector>

class MyClass
{
    private:
        MyClass();
    public:
        MyClass(unsigned i) : _data(i) {};

    private:
        unsigned _data;
};

typedef std::vector<MyClass> MyVector;

void MyVector::resize(MyVector::size_type new_size)
{
    this->resize(new_size, MyClass(5));
}

int main()
{
    MyVector vector;
    vector.resize(5);

    return 0;
}

Но помислете дали наистина имате нужда от това. Защо вместо това не създадете конструктор по подразбиране?

person Roman Nikitchenko    schedule 06.11.2009