How to initialize a static vector member?

for instance

struct A { static vector<int> s; }; vector<int> A::s = {1, 2, 3}; 

However, my compiler does not support an initialization list. Any way to implement it easily? Does the lambda function help?

+6
source share
5 answers

How easy is it to implement it?

There is nothing particularly elegant. You can either copy data from a static array or initialize it with a function call. The former may use more memory than you would like, and the latter needs some slightly dirty code.

Boost has a library to make this a little less ugly:

 #include <boost/assign/list_of.hpp> vector<int> A::s = boost::assign::list_of(1)(2)(3); 

Does the lambda function help?

Yes, this can save you from having to call a function just to initialize 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 the return . Some compilers accept my version, and I believe that it will become standard in 2014 year.)

+4
source

I am always afraid of being hit for an initialization order here for such questions, 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 that you should = P

Winning the reward for the least effective 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 hit at compile time if T and something in Args ... doesn't match type or type. Of course, if you have variations in template options, you also have initializer lists, but that makes brainwashing fun if nothing else.

+4
source

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(); 
+3
source

You can initialize 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 consider this in the template function:

 template<typename T, int n> std::vector<T> from_array(T (&v)[n]) { return std::vector<T>(v, v+n); } 
+1
source

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)); 
0
source

Source: https://habr.com/ru/post/953998/


All Articles