简体   繁体   中英

Assign array's values at compile time with and enum as index (C++)

I'm trying to use a C-style array as a map through enums but I can't initialize arrays by parts... I'll explain myself better through code:
I have something like:

enum Objects{CAR = 0, PLANE, BOY};

I have:

static const char* texturePaths[] = {"..\\car.png", "..\\plane.png", "..\\boy.png"};

and that actually works the way I want, ie

initTexture(texturePaths[CAR]);

but in this way I must to make sure that I'm declaring in the same order both enum and array. I'd like to do something like this:

enum Objects{CAR = 0, PLANE, BOY, size};
const char* texturePaths[Objects::size];
texturePaths[BOY] = "..\\boy.png";
texturePAths[CAR] = "..\\car.png";
...

I know that could work, but I need to do it inside a function and call it, so run time. I want to do it at compile time because there are constant values that will never change and it's a waste to do it at run time.
I also know that constexpr could do it through lambda functions, but I don't know how to do it

You tagged constexpr , so you can use C++11 or newer, so you can use std::array . Generic suggestion: use std::array , when possible, instead old C-style arrays.

I want to so it at compile time

If you accept a C++17 solution (?) you can use the fact that the not-const version of operator[] for std::array is (starting from C++17) constexpr .

So you can create a constexpr function to initialize the std::array as you want

enum Objects{CAR = 0, PLANE, BOY, size};

constexpr auto getTexturePath ()
 {
   std::array<char const *, Objects::size>  ret {{}};

   ret[BOY] = "..\\boy.png";
   ret[CAR] = "..\\car.png";
   // ...

   return ret;
 }

and save the result in a constexpr (important!) variable

   constexpr auto texturePath { getTexturePath() };

The following is a full compiling C++17 example with some static_assert() as proof that the initialization of texturePath is done compile-time.

#include <array>
#include <type_traits>

enum Objects{CAR = 0, PLANE, BOY, size};

constexpr auto getTexturePath ()
 {
   std::array<char const *, Objects::size>  ret {{}};

   ret[BOY] = "..\\boy.png";
   ret[CAR] = "..\\car.png";
   // ...

   return ret;
 }

int main()
 {
   constexpr auto texturePath { getTexturePath() };

   static_assert( texturePath[CAR][3] == 'c' ); 
   static_assert( texturePath[CAR][4] == 'a' ); 
   static_assert( texturePath[CAR][5] == 'r' ); 
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM