0

I have a template class that's a simple vector, but this piece of code refuses to compile:

template<int t>
struct Vector {
 int pos[t];
 Vector(int other[t]) {
  for (int i = 0;i < t;++i) {
   pos[i] = other[i];
  }
 }
};

Vector<3> cake = {3,4,5};

This is the error:

Line 11: error: scalar object 'cake' requires one element in initializer
compilation terminated due to -Wfatal-errors.

Why doesn't this work? What's the simplest way to make it work similarly to this?

EDIT:

Neither does this work:

Vector<3> cake({3,4,5});

Isn't that supposed to call a constructor with signature Vector<3>(int[3])?

slartibartfast
  • 4,348
  • 5
  • 31
  • 46

1 Answers1

2

In C++03, the initializer form of {} is allowed for only aggregates (which includes POD also).

The class template in code is not POD, neither is it aggregate. Read my answer here to know the definition of POD and Aggregate.

Once you know the definitions, you'll know what you can do to make your class POD (if you want to).

However, in C++11, you can use {} initializer, but you've use std::initializer_list<T> as the parameter type of the constructor. Then you can use {} even for types which are not POD and Aggregate!

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Is there any way to make a template a POD? If not, why do I have to use `std::initializer_list`? Isn't it supposed to be a language feature, not a library feature? – slartibartfast Dec 03 '11 at 18:51
  • @myrkos: Go through the links and know the definition of POD and aggregate! – Nawaz Dec 03 '11 at 18:53
  • Oh, thanks. So I can make my Vector class an aggregate just by removing the constructor? Will that work? – slartibartfast Dec 03 '11 at 18:55
  • @myrkos: Try. Experiment. Compile. And See! – Nawaz Dec 03 '11 at 18:56
  • Golly jeepers! It works! But I have to use two braces `Vector<3> cake = {{3,4,5}};` but just out of curiosity, why doesn't `Vector<3> cake({3,4,5})` work int he first place? Isn't it supposed to call the constructor that takes an array as an argument? – slartibartfast Dec 03 '11 at 19:00
  • @myrkos: You're asking the same question. Why should it work, when it is not POD? – Nawaz Dec 03 '11 at 19:03
  • Because I've made a constructor that takes an array as argument, and supposedly I want to call said constructor when saying `Vector<3>({1,2,3})`? Isn't that how you call constructors? – slartibartfast Dec 03 '11 at 19:04
  • @myrkos: `{1,2,3}` cannot be passed as argument in C++03. – Nawaz Dec 03 '11 at 19:07
  • @myrkos: Yes. But you've to use `std::initializer_list` as parameter type. – Nawaz Dec 03 '11 at 19:10
  • Also, `int other[t]` in the constructor parameter decays into `int *other`. Which means you pass array of any size to the constructor; `t` has no role in the parameter type! – Nawaz Dec 03 '11 at 19:11
  • Why so? What does initializer_list do that a regular programmer can't? – slartibartfast Dec 03 '11 at 19:11
  • @myrkos: That is how the committee has designed the language. To know the rationale, you've to read the proposal paper which introduced the feature. – Nawaz Dec 03 '11 at 19:12