Reputation: 13575
For example
struct A
{
static vector<int> s;
};
vector<int> A::s = {1, 2, 3};
However, my compiler doesn't support initialization list. Any way to implement it easily? Does lambda function help here?
Upvotes: 6
Views: 25698
Reputation: 114481
You can initialize an std::vector
from two pointers
int xv[] = {1,2,3,4,5,6,7,8,9};
std::vector<int> x(xv, xv+(sizeof(xv)/sizeof(xv[0])));
You can even factor this out in a template function:
template<typename T, int n>
std::vector<T> from_array(T (&v)[n]) {
return std::vector<T>(v, v+n);
}
Upvotes: 1
Reputation: 66194
I always fear being shot down for initialization ordering here for questions like this, but..
#include <iostream>
#include <vector>
#include <iterator>
struct A
{
static std::vector<int> s;
};
static const int s_data[] = { 1,2,3 };
std::vector<int> A::s(std::begin(s_data), std::end(s_data));
int main()
{
std::copy(A::s.begin(), A::s.end(),
std::ostream_iterator<int>(std::cout, " "));
return 0;
}
Output
1 2 3
Just because you can doesn't mean you should =P
Winning the award for the least efficient way to do this:
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
template<typename T>
std::vector<T> v_init(const T& t)
{
return std::vector<T>(1,t);
}
template<typename T, typename... Args>
std::vector<T> v_init(T&& t, Args&&... args)
{
const T values[] = { t, args... };
std::vector<T> v1(std::begin(values), std::end(values));
return v1;
}
struct A
{
static std::vector<int> s;
};
std::vector<int> A::s(v_init(1,2,3,4,5));
int main(int argc, const char *argv[])
{
std::copy(A::s.begin(), A::s.end(), std::ostream_iterator<int>(std::cout, " "));
return 0;
}
Output
1 2 3 4 5
This should puke at compile-time if T and anything in Args... is not type-compliant or type-castable. Of course, if you have variadic templates odds are you also have initializer lists, but it makes for fun brain-food if nothing else.
Upvotes: 4
Reputation: 76529
Write a simple init function for the vector:
vector<int> init()
{
vector<int> v;
v.reserve(3);
v.push_back(1);
v.push_back(2);
v.push_back(3);
return v;
};
vector<int> A::s = init();
Upvotes: 3
Reputation: 14603
Another idea:
struct A
{
static std::vector<int> s;
};
std::vector<int> A::s;
static bool dummy((A::s.push_back(1), A::s.push_back(2), A::s.push_back(3), false));
Upvotes: 0
Reputation: 254461
Any way to implement it easily?
There's nothing particularly elegant. You can either copy the data from a static array, or initialise it with the result of a function call. The former might use more memory than you'd like, and the latter needs some slightly messy code.
Boost has a library to make that slightly less ugly:
#include <boost/assign/list_of.hpp>
vector<int> A::s = boost::assign::list_of(1)(2)(3);
Does lambda function help here?
Yes, it can save you from having to name a function just to initialise the vector:
vector<int> A::s = [] {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
return v;
}();
(Strictly speaking, this should have an explicit return type, []()->vector<int>
, since the lambda body contains more than just a return
statement. Some compilers will accept my version, and I believe it will become standard in 2014.)
Upvotes: 4