0

I created an array template for my personal use.

template <typename T, int size>
struct Vector {
    T data[size];
};

I tried to intialize the data like so:

Vector<unsigned char, 10> test;
test.data[] = {0,1,2,3,4,5,6,7,8,9};

My compiler ended up complaining something about "expected expression." Does anyone know what I'm doing? I want to be able to use this style of initialization where you give it the entire array definition at once instead of using a for loop to init the elements individually.

1
  • 1
    Unless you plan on adding more things to that struct, I think you would be better off using plain old arrays. Commented Dec 10, 2011 at 17:13

4 Answers 4

3

Since your class is an aggregate, you can initialize it with the usual brace syntax:

Vector<int, 3> x = { { 1, 2, 3 } };

The exact same thing applies to std::array<int, 3>.

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

Comments

2

In the new standard, C++11, you can use std::initalizer_list to get the desired result, see the below example.

#include <iostream>
#include <algorithm>

template <typename T, int size>
struct Vector {
  T data[size];

  Vector<T, size> (std::initializer_list<T> _data) {
    std::copy (_data.begin (), _data.end (), data);
  }
  // ...

  Vector<T, size>& operator= (std::initializer_list<T> const& _data) {
    std::copy (_data.begin (), _data.end (), data);
    return *this;
  } 
};

int
main (int argc, char *argv[])
{
  Vector<int, 10> v ({1,2,3,4,5,6}); // std::initializer_list

  v = {9,8,7,6,5,4,3,2,1,0}; // operator=
}

If you are working with a standard prior to C++11 it's a bit more of a hassle really, and your best bet is to implement functions similar to those available when using std::vector.

#include <iostream>
#include <algorithm>

template <typename T, int size>
struct Vector {
  T _data[size];

  Vector (T* begin, T* end) {
    std::copy (begin, end, _data);
  }   

  // ...

  void assign (T* begin, T* end) {
    std::copy (begin, end, _data);
  }   
};  

int 
main (int argc, char *argv[])
{   
  int A1[4] = {1,2,3,4};
  int A2[5] = {99,88,77,66,55};

  Vector<int, 10> v1 (A1, A1+4);

  // ...

  v1.assign (A2, A2+5);
} 

4 Comments

Your first example won't compile.
@jrok I see nothing wrong with the snippet, care to enlighten me?
GCC says: "error: assigning to an array from an initializer list" for last line in first snippet.
@jrok ah, right.. I had a vague memory of assignment from std::initializer_list to T[] made it into c++11, but I guess it was only a c++0x gcc draft implementation. Snippet changed.
0

You have to supply the type and size of the array when defining the variable:

Vector<int, 10> test;

You can not however assign to the member array like a normal array. You have to assign each element separately:

for (int i = 0; i < 10; i++)
    test.data[i] = i;  // If instantiated with type "int"

1 Comment

"You can not however assign to the member array like a normal array." Not true anymore in C++11.
0

You can only initialize an array at the point you are defining it:

Vector<unsigned char, 10> test;

There's your array, you are done defining it, your chance to initialize it has passed.

Edit: Seeing Mat's answer, memo to me: I have to read up on C++11, and soon... :-/

Edit 2: I just gave the information on what was wrong. Kerrek SB has the information on how to do it right. ;-)

1 Comment

I think I was wrong, and you are correct - that syntax is for initialization only...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.