7

I am wondering if there are some way to initialize a vector using an enum. The enum is necessary because I am creating a vector of objects (same class, Chess_piece, but different type). I want to be able to access the element without a lot of tests (if (this is white pawn 8)...). The enum can be used to itemize the pieces in a nice way vec(W_PAWN8).... Anyway when I create vector I do something like this (pseudo code)

//generate enum of pieces
enum pieceList{
...
} pieceEnum;
vector<int> pieceIter = {W_PAWN1,W_PAWN2,...}; //equal to {1,2,...}
//board index goes from lower left to upper right
vector<int> boardIdx = {8,9,10,11,12,13,14,15,16,1...};
vector<Piece*> pieceVec;
for (int i=0; i<32; i++)
    pieceVec.pushback( new Piece( boardIdx(i), pieceIter(i) ) );

However, now I actually write the same thing 2 times. Both when I create the enum and pieceIter. For this program I can live with it, but I may have the same issue more than once.

This is why I wonder, does it exist something like vector<int> pieceIter {pieceEnum}; in c++? The code snippet in the previous sentence is invalid of course, but I think it hints my problem, to use all variables in the enum and initialize the vector in a simple way?

If not, is it possible to use some kind of "range initialization" for vector like in matlabl Something like:

vector<int> vec {1:32};

But with c++ syntax?

patrik
  • 4,506
  • 6
  • 24
  • 48
  • `std::iota` = 1 possibility. that said, when you lack tool, create it. – Cheers and hth. - Alf Dec 17 '14 at 18:17
  • @Cheersandhth.-Alf That is of course a possibility, I did not know about `std::iota`. Thanks! I guess that the other way, initializing a vector/array with an enum may require some more work. And possibly support from the compiler. – patrik Dec 17 '14 at 18:34
  • @patrik This isn't an attempt to answer the question, but this would make more sense to me as a `std::map` and have the `boardIdx` be a member of the `Piece`. – Jonathan Mee Dec 17 '14 at 18:49
  • possible duplicate of [Set std::vector to a range](http://stackoverflow.com/questions/11965732/set-stdvectorint-to-a-range) – Jonathan Mee Dec 17 '14 at 18:50
  • @JonathanMee That may be true actually, however, would I be able to do something like `Piece p = myMap(W_PAWN8);` with this setup? The important thing here is that each index have a name. I will swear a lot if I need to remember the indices, but I will never have a problem with `W_PAWN8`. – patrik Dec 17 '14 at 19:07
  • @patrik Yup that is exactly how it would work. If your interested in doing the overhaul, I'd suggest asking another question about how to make the conversion. If you comment with a link I'll go try to answer. – Jonathan Mee Dec 17 '14 at 19:12
  • @JonathanMee That would be great! Here is the [link](http://stackoverflow.com/questions/27533518/how-to-build-a-map-were-the-key-is-an-enum) – patrik Dec 17 '14 at 19:40
  • 1
    @patrik Welp, I did this to you. Sorry StackOverflow is so hateful of late. Another note on the context here though: I assume your `std::map`'s value is actual `Pieces`? Cause it doesn't really make sense to use a map to an index for a `std::vector`. – Jonathan Mee Dec 17 '14 at 20:28
  • @JonathanMee Yes that is right. Thank you for your help, I think I manage everything now :) – patrik Dec 17 '14 at 20:35

3 Answers3

4

One way to solve this would be adding a value to the enum that is always the last one. Then you could fill the vector by looping up to the value. Something like this:

enum VALUES{

    VALUES_FIRST = 0,

    VALUES_SECOND,

    VALUES_END
};

std::vector<VALUES> Allvalues;

for(int i = 0; i < VALUES_END; i++){
    Allvalues.push_back(static_cast<VALUES>(i));
}

Would fill the vector with all the values in the enum (not including the last marker value) as long as you don't put anything after VALUES_END.

  • I see, that would work for a enum increasing with steps of 1, starting at 0 at least. However, I guess that you mean `i <= VALUES_LAST` or `i – patrik Dec 17 '14 at 18:56
  • As far as I know C++ doesn't store the enum values so that you could retrieve them at runtime making it impossible to iterate over the enum values. – Henri Hyyryläinen Dec 18 '14 at 17:05
3

So if you want to generate a range from 1 to 32 you can use generate to do that, combined with a lambda.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> v(32);
    int n=0;
    std::generate(v.begin(), v.end(), [&]{ return ++n; }); 

    //to display the results
    for (auto& it: v){
        cout<<it<<" ";
    }
    return 0;
}

Output: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

Hope that helps

Gabriel
  • 3,564
  • 1
  • 27
  • 49
0

You can also use the vectors constructor to initialize the vector like follows:

enum MyEnum {
  FIRST,
  SECOND,
  THIRD
};

// Example 1:
vector<int> v1(4, MyEnum::FIRST); // init a vector of size 4 to "FIRST".

// Example 2:
vector<MyEnum> v2(4, MyEnum::SECOND); // int a vector of enums.

// Example 3
vector<int> v3 {MyEnum::FIRST, MyEnum::THIRD}; // vector of int of size 2 with different values.

// Example 4:
vector<MyEnum> v4 {MyEnum::FIRST, MyEnum::THIRD}; // vector of enum.
A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128