Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize static vector member?

Tags:

c++

static

lambda

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?

like image 831
user1899020 Avatar asked Sep 17 '13 15:09

user1899020


People also ask

How do you initialize a static member in C++?

For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator (::), then the variable name. Now we can assign some value. The following code will illustrate the of static member initializing technique.

How do you initialize a vector in a class C++?

How to Initialize a Vector in C++ Using the push_back() Method. push_back() is one out of the many methods you can use to interact with vectors in C++. It takes in the new item to be passed in as a parameter. This allows us to push new items to the last index of a vector .

Does std::vector need to be initialized?

when you create a vector it gets default initialized, so it's up to you if you want to initialize it with user default values or not. You will always get an empty vector container if you don't initialize it.


4 Answers

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.)

like image 113
Mike Seymour Avatar answered Oct 02 '22 00:10

Mike Seymour


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.

like image 44
WhozCraig Avatar answered Oct 02 '22 00:10

WhozCraig


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();
like image 38
rubenvb Avatar answered Oct 01 '22 22:10

rubenvb


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);
}
like image 36
6502 Avatar answered Oct 02 '22 00:10

6502