0

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

Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305

5 Answers5

1

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

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Correct me if i'm wrong, but your code introduce copy-constructor. My `OneItemIndex` objects are not supposed to be copied. – Oleg Vazhnev Apr 23 '14 at 12:05
  • i've trited to use `oneItemIndexes.emplace_back(i);` but this doesn't work too because of this http://stackoverflow.com/questions/20595079/why-is-copy-constructor-called-in-call-to-stdvectoremplace-back – Oleg Vazhnev Apr 23 '14 at 12:16
  • @javapowered: Yes, vector elements must be copyable or moveable. This is the first time you've indicated that it may be a problem for you. Next time state _all_ relevant detail in the question, please. – Lightness Races in Orbit Apr 23 '14 at 13:07
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));
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • note that in VC++ copy-constructor must be public even if it will not be used http://stackoverflow.com/questions/20595079/why-is-copy-constructor-called-in-call-to-stdvectoremplace-back – Oleg Vazhnev Apr 23 '14 at 12:33
  • I've found that VC++ actually "calls" copy-constructor when `emplace_back` is called, so I would say it's unusable in VC++ – Oleg Vazhnev Apr 23 '14 at 12:38
0

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

graham.reeds
  • 16,230
  • 17
  • 74
  • 137
0

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

dlf
  • 9,045
  • 4
  • 32
  • 58
  • it seems `oneItemIndexes.emplace_back(i);` should work fine and no shared pointer is required. – Oleg Vazhnev Apr 23 '14 at 12:25
  • It depends. We don't see the full definition of OneItemIndex, but if the copy constructor is explicitly hidden (which I'm assuming based on the followup comments), emplace_back won't work either. – dlf Apr 23 '14 at 12:44
0

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);
}
Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305