stl vector и c++: как изменить размер без конструктора по умолчанию?

Как указать 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)


Используйте перегрузку с двумя аргументами: 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