While declarations and initializations outside of a function (such as main
) are no problems, you cannot have code outside of functions. You either need to set the value right at the initialization (as in C++11), or fill your global object in main:
std::vector<string> Aries;
/* ... */
int main() {
Aries.push_back("Taurus");
/* ... */
}
Other ways (without populating the vector in main)
Single values
There are other ways which don't need .push_back
or other code in the main. For example, if Aries
shall contain only one item, you can use std::vector<T>::vector(size_t s, T t)
with s == 1
and t == "Taurus"
:
std::vector<string> Aries(1, "Taurus");
/* ... */
int main() { /* ... */ }
If you need the same value several time you can simply adjust s
.
Multiple distinct value
Now this gets a little bit trickier. You want to populate the vector
by using a suitable constructor. std::vector<T>
provides four different constructors in C++03:
std::vector<T>::vector()
std::vector<T>::vector(size_t, T = T())
template <class InputIt> std::vector<T>::vector(InputIt, InputIt)
std::vector<T>::vector(const vector&)
Note that all of them actually take an allocator as additional last parameter, but this is not of our concern.
We can forget about std::vector<T>::vector()
, since we want to fill the vector with values, and also std::vector<T>::vector(size_t, T)
doesn't fit, since we want distinct values. What's left is the templated constructor and the copy constructor. The following example shows how to use the templated constructor:
std::string const values[] = {"Taurus", "Ares", "Testos"};
template <class T, size_t N>
T* begin(T (&array)[N]){ // this is already in C++11, very helpful
return array;
}
template <class T, size_t N>
T* end(T (&array)[N]){
return array+N;
}
std::vector<std::string> Aries(begin(values), end(values));
Note that begin
and end
aren't necessary - we could simple use Aries(values, values+3)
. However, things tend to change, and often you add a value or remove one. If you forget to change the offset 3
you would either forget an entry or cross borders of values
.
However, this solution introduces a new global variable, which aren't that nice. Lets take a step back. We needed values
since we wanted to use std::vector<T>::vector(InputIt, InputIt)
, which needs a valid range. And the range must be known at the time we use the constructor, so it needs to be global. Curses! But behold: our toolbox still contains one constructor, the copy constructor. In order to use it we create an additional function:
namespace {
std::vector<std::string> initializer(){
const std::string dummy_array[] = {"Taurus", "Ares", "Testos"};
return std::vector<std::string>(begin(dummy_array), end(dummy_array));
}
}
std::vector<std::string> Aries(initializer());
This example uses both copy constructor and range constructor. You could also create a temporary vector and use std::vector<T>::push_back
to populate it in the function.