2

I have the following lines in my code:

#define NUM_THREADS 8 // NUM_THREADS is variable

myClass myVar[NUM_THREADS] {{&A,&x}};

A and x are just variables that are used in the myClass constructor to setup the size of some variables of the myVar objects. However, the values of A and x aren't known until run time.

Since NUM_THREADS is variable, what I want is for every object (i.e. myVar[NUM_THREADS-1:0] to get the same values sent in for the constructor, without having to manually type out the following.:

myClass myVar[NUM_THREADS] {{&A,&x},{&A,&x},{&A,&x},{&A,&x},{&A,&x},{&A,&x},{&A,&x},{&A,&x}};

Here's what the constructor looks like:

myClass::myClass(Aclass *A_orig, Xclass *x_orig) { 
  A_new = *A_orig;
  x_new = *x_orig;
}
1
  • 3
    You might write a variadic template struct that ultimately yields a std::initializer_list. I have to think a moment about how such could look like. Or maybe somebody else more versed in template meta-programming will give you an example. Commented Nov 4, 2016 at 18:17

4 Answers 4

4

You can use std::index_sequence to generate numbers from 0 to N in a parameter pack. This is how I'd do it:

MyClass&& make_my_class(std::size_t, MyClass&& m) { return std::move(m); }

template<std::size_t... S>
void makeThreads(std::index_sequence<S...>) {
    std::array<MyClass, S> myVar{make_my_class(S, {&A,&x})...};
}

template<std::size_t N>
void makeThreads() {
    makeThreads(std::make_index_sequence<N>{});
}

Now, you can use it like that:

constexpr std::size_t numberOfThreads = 8;

makeThreads<numberOfThreads>();

The advantage of this solution is that the resulting code is exactly the same as if you'd wrote it by hand.

One disadvantage of this solution is that you have to know the number of thread you want at compile-time, whereas the solution using vectors is allowed to determine the size at runtime. It make sense, as you ask the compiler to fill the braces for you. For the compiler to do it, it has to know the number of MyClass you want it to repeat in the array initialization.

Sign up to request clarification or add additional context in comments.

7 Comments

How do you think your answer compares with using std::vector?
Well, this one works when you have a number of threads known at compilation. There is no dynamic allocation here. The code expands just like if you'd wrote the whole array by hand.
@Veridian this one actually directly answers your question :)
@GuillaumeRacicot I would use a wrapper structure instead of function though :)
@Veridian As long as you know the number of thread you want at compile-time, there is only upsides.
|
3

I suggest that you use an std::vector:

std::vector<MyClass> v1(20, MyClass(&A,&x)); // Initialize a vector with 20 instances of MyClass.

3 Comments

This worked for me, very simple solution too, thanks.
How do you think your answer compares with @GuillaumeRacicot's
I think it depends on your needs, but in general, using a standard library functionality is simpler than writing a function.
2

Create the array and construct each of the objects in a loop.

myClass myVar[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; ++i) myVar[i] = myClass(A, x);

You are default constructing objects first, but that isn't necessarily a problem. A better solution might be to provide setters for both of those fields and set them in the loop if you don't mind them being mutable.


Really, though, you should probably be using std::vector or std::array if you support them.

Comments

0

I do not think it is possible without using a dedicated function. However you can test with std::fill or std::fill_n from the algorithm header.

Here is a sample:

#include <iostream>
#include <algorithm>

class AClass
{
public:
  AClass() {}
  AClass(int a, int b) : a(a), b(b) {}

  int getA() { return a; }
  int getB() { return b; }
private:
  int a;
  int b;
};

int main()
{
  AClass aclass[8];
  std::fill_n(aclass, 8, AClass(1, 2));

  for (int i = 0; i < 8; ++i)
  {
      std::cout << aclass[i].getA() << aclass[i].getB() << "\n";
  }

  std::cin.get();
  return 0;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.