-1

I have a class hi with a non-default constructor taking two arguments. I'm trying to construct an array of his:

class hi {
  public:
    hi(int a, int b){};
};

int main() {
  hi *hello;
  int number_of instance = 5;
  hello = new hi[number_of_instance]; // (1)
}

How to invoke hi::hi(int,int) on the line marked (1)?

YSC
  • 38,212
  • 9
  • 96
  • 149
Zeeshan Hayat
  • 401
  • 6
  • 13

2 Answers2

6

How to invoke hi::hi(int,int)?

If hi is actually an aggregate type and/or you're using C++11, you can built it simply with:

hello = new hi[5]{{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}};

If hi is not an aggregate, per se you cannot. But with a bit of improvement, we can achieve it.

  1. Declare a private default constructor:

This gives:

class hi {
    hi();
public:
    hi(int a, int b){};
};

Thhe idea is to provide a default constructor for the standard container to find, even though std::is_default_constructible_v<hi> is false. Obviously, any actually attempt to default construct an hi will end in a compilation failure.

  1. Use an std::array or a std::vector instead of a C array:

This gives:

std::vector<hi> his;
  1. Use std::generate_n to construct your objects:

This gives:

his.reserve(number_of_instances);
std::generate_n(std::back_inserter(his), number_of_instances, [](){ return hi{0, 0}; });

Note though, this vector as a vector of non-default constructibe type is uncomplete, you'll be unable to use all of its features.

Demo

Another approach would be to reserve some memory as arrays of unsigned char and construct his instances in it with placement news.

default
  • 11,485
  • 9
  • 66
  • 102
YSC
  • 38,212
  • 9
  • 96
  • 149
  • 1
    Can you explain the reason behind the private default constructor? This however does not answer the original question :/ – Jorge Bellon Apr 23 '18 at 08:22
  • 2
    Reserved memory doesn't count towards the range of the vector. Here `begin(his) == end(his)` – Passer By Apr 23 '18 at 08:27
  • `std::generate_n(std::back_inserter(his), number_of_instances, [](){ return hi{0, 0}; });` – Caleth Apr 23 '18 at 08:28
  • @PasserBy This is not the first time I make this mistake. Thx Caleth, taken as is. – YSC Apr 23 '18 at 08:29
  • Thanks for the edit. I would use [`std::aligned_storage`](http://en.cppreference.com/w/cpp/types/aligned_storage) instead of `char[]`. It will provide you the same properties, but ensuring all the items are aligned properly (you can get very nasty problems at runtime otherwise). – Jorge Bellon Apr 23 '18 at 08:32
  • @PasserBy this has been turned into a com' wiki. It's all yours to improve. – YSC Apr 23 '18 at 08:52
  • why was the call to `generate` incorrect? I'm trying to grasp the difference but I think I'm failing miserably :) – default Apr 23 '18 at 08:53
  • 1
    @Default look at PasserBy's comment ;) – YSC Apr 23 '18 at 08:55
  • 1
    @Default Jorge comments the last sentence of this answer _"Another approach would be to reserve some memory as arrays of unsigned char and..."_ – YSC Apr 23 '18 at 09:08
0

Use a vector

std::vector<hi> hello{{1,2},{1,2},{1,2},{1,2},{1,2}};
BartekPL
  • 2,290
  • 1
  • 17
  • 34