2

It works for struct RS : public JV<T,1> but not for struct RS : public JV<T,2>.

error: could not convert ‘{(0, j), (0, j)}’ from ‘<brace-enclosed initializer list>’ to ‘WJ<float>’

Do I have to overload operator,() ? Code:

#include<iostream>

struct B {};

template <std::size_t... Is>
struct indices {};

template <std::size_t N, std::size_t... Is>
struct build_indices
  : build_indices<N-1, N-1, Is...> {};

template <std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...> {};

template<class T,int N>
struct JV {

  JV(B& j) : JV(j, build_indices<N>{}) {}
  template<std::size_t... Is>
  JV(B& j, indices<Is...>) : jit(j), F{{(void(Is),j)...}} {}

  B& jit;
  T F[N];
};

template<class T>
struct RS : public JV<T,2>
{
  RS(B& j): JV<T,2>(j) {}
};

template<class T>
struct WJ
{
  WJ(B& j) {
    std::cout << "WJ::WJ(B&)\n";
  }
};

int main() {
  B j;
  RS<WJ<float> > b2(j);
}
ritter
  • 7,447
  • 7
  • 51
  • 84

3 Answers3

4

You need to remove the extra {} if you want to use a plain array F{(void(Is),j)...}. Or change it to std::array<T, N> F like you said.

A plain array simply uses {} for initialization, however and std::array is an aggregate which contains an array, so it uses the double braces.

See Using std::array with initialization lists for a better explanation.

Community
  • 1
  • 1
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
2

Your problem is an extra pair of {} braces. Change

  JV(B& j, indices<Is...>) : jit(j), F{{(void(Is),j)...}} {}

to

  JV(B& j, indices<Is...>) : jit(j), F{(void(Is),j)...} {}

and it works fine.

The reason it works with std::array is that array is an aggregate containing an actual array:

// from 23.3.2.1 [array.overview]
namespace std {
  template<typename T, int N>
  struct array {
...
    T elems[N];    // exposition only

So to initialise array, an extra pair of braces is required compared to initialising an actual array. gcc allows you to omit the extra braces, but complains:

  std::array<int, 3>{1, 2, 3};

warning: missing braces around initializer for 'std::array::value_type [3] {aka int [3]}' [-Wmissing-braces]

ecatmur
  • 152,476
  • 27
  • 293
  • 366
1

Replacing

 T F[N];

with

 std::array<T,N> F;

did the trick! It seems std::array can do more than C arrays.

ritter
  • 7,447
  • 7
  • 51
  • 84
  • 3
    It's not necessarily that `std::array` can do more than C-style arrays, it's just that the initialization behaves differently. C-style need only one pair of braces, while `std::array` is an aggregate (thus allowing `{...}` initialization even in C++03). The second pair of braces is for the inner C-style array member. – Xeo Oct 12 '12 at 10:46