initialing stl collection elements (not pointers) when no default constructor?

时光毁灭记忆、已成空白 提交于 2021-02-11 16:47:32

问题


I have such private field:

private:
    std::vector<OneItemIndex> oneItemIndexes;

My class declared this way, there are no default constructor:

public OneItemIndex(int instrumentId)

I want my field to contain 10 elements like this:

oneItemIndexes
    0 OneItemIndex(0)
    1 OneItemIndex(1)
    ...
    10 OneItemIndex(10)

How can I do this? What should I write in constructor? Is it possible?

Or I have to use OneItemIndex* instead of OneItemIndex and call new OneItemIndex(instrumentId myself this way?

IndexesStorage::IndexesStorage(void)
{
    for (int i = 0; i < 10; i++) {
        oneItemIndexes.push_back(new OneItemIndex(i));
    }
}

Note: actually I dont' have hardcoded 10 elements, i'm using dynamic Instrument::InstrumentsCount()


回答1:


In C++11 and later, you can initialise container elements by passing constructor arguments to an emplace function:

oneItemIndexes.emplace_back(i);

Historically, you could copy-initialise them (as long as they're copyable; but that was a requirement for vector before C++11):

oneItemIndexes.push_back(OneItemIndex(i));



回答2:


I don't understand the leap to dynamic allocation in the middle of your question. Why do you think you suddenly have to use dynamic allocation and store pointers?

Use your loop, but with normal, automatic-storage-duration objects. oneItemIndexes.push_back(OneItemIndex(i)) or even oneItemIndexes.emplace(i).




回答3:


You could use std::generate. Sorry for brevity of my answer but I am on my phone.




回答4:


If you really don't want to make your object default-constructible and copyable, the easiest way to solve this would be to use a vector of shared_ptrs to OneItemIndex. This way you get the copy/initialize semantics vector requires from shared_ptr, but you don't need to have them on OneItemIndex itself (a raw pointer would work too, but then you need to take care of deleting the elements somewhere).




回答5:


Adding my code which works so far. I'm not sure how stable this code and how safe to use such hacks. To avoid calling copy-construct I have to call reserve

IndexesStorage::IndexesStorage(void)
{
oneItemIndexes.reserve(Instrument::InstrumentsCount());
for (int i = 0; i < Instrument::InstrumentsCount(); i++) {
    oneItemIndexes.emplace_back(i);
}
}

OneItemIndex::OneItemIndex(OneItemIndex& rhs):
CustomIndex("blabla")
{
    printf("OneItemIndex copy-construct must not be called, we make it public cause MSVC++ implementation!");
    exit(0);
}


来源:https://stackoverflow.com/questions/23243282/initialing-stl-collection-elements-not-pointers-when-no-default-constructor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!