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

StackOverflow https://stackoverflow.com/questions/23243282

  •  08-07-2023
  •  | 
  •  

Domanda

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()

È stato utile?

Soluzione

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));

Altri suggerimenti

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).

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

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).

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top