2011-08-30 1 views
3

У меня есть вектор объектов. Каждый объект имеет boost::shared_ptr не подлежащему копированию объекту (boost::signal). конструктор по умолчанию объекта создает объект boost :: signal.Как изменить размер std :: vector с уникальными объектами

struct FuncRef 
{ 
    typedef boost::signal0<void, > Func; 
    boost::shared_ptr <Func> function; 
    FuncRef(): 
     function(new Func) 
    { 
    } 
}; 

Чтобы установить мой вектор содержит X отдельные объекты, я сделал это: -

vec.resize(X); 

Это не делать то, что я ожидал, потому что он использует конструктор по умолчанию, чтобы сделать один объект, и затем конструктор копирования, чтобы сделать дубликаты. Я в конечном итоге с X объектов, но все они указывают на тот же объект boost::signal0.

Есть ли более простой способ построения моего вектора правильно, чем просто использовать push_back в цикле for?

+0

Вы можете сделать свой класс наследованием 'boost :: noncopyable' для обнаружения таких ошибок во время компиляции. –

+0

@Bjorn - класс должен быть скопирован, так как он находится в векторе. Вот почему я должен использовать shared_ptr. Проблема в том, что он использует копирование, когда я этого не ожидал ... – Roddy

+0

Правильно, о чем я думал? –

ответ

3

Единственный способ, я могу думать о том, чтобы использовать reserve, чтобы вектор выделил нужную вам память (как ответил @Jonathan). Вы можете использование generate_n с std::back_inserter, чтобы добавить элементы:

FuncRef makeFuncRef() { 
    return FuncRef(); 
} 

vec.reserve(vec.size() + n); 
std::generate(std::back_inserter(vec), n, makeFuncRef); 

reserve не надо с этим подходом, хотя это, вероятно, быстрее, если n велико.

1

Самый простой способ, которым я могу думать о том, чтобы зарезервировать память заранее, таким образом, что только один распределение требуется по vector:

vec.reserve(X); 

Затем цикл и push_back(). Этого недостаточно для ваших нужд?

+0

Да, это работает, но мне было интересно, есть ли простой однострочный ящик, которого я отсутствовал ... – Roddy

+0

Björn имеет правильную идею с 'std :: generate()' Я думаю. Непонятно, что вы хотите инициализировать элементы вектора * до *. Они должны содержать некоторое значение (или быть неопределенным). –

+0

инициализируется по умолчанию построенными объектами, используя конструктор FuncRef shwon в коде. Код Бьорна будет работать как есть, но для циклов лучше читаемость ИМО. Roll on lambdas ... – Roddy

0

Не удалось ли реализовать конструктор копирования/назначение копии с использованием фактической семантики? Если у вас нет серьезной работы с заполнением вектора, это кажется самым очевидным решением.

Смежные вопросы