Я пытаюсь использовать массив в стиле C как карту с помощью перечислений, но не могу инициализировать массивы по частям … Я объясню себя лучше с помощью кода:
У меня есть что-то вроде:
enum Objects{CAR = 0, PLANE, BOY};
Я имею:
static const char* texturePaths[] = {"..\\car.png", "..\\plane.png", "..\\boy.png"};
и это на самом деле работает так, как я хочу, т.е.
initTexture(texturePaths[CAR]);
но таким образом я необходимость, чтобы убедитесь, что я заявляю в тот же порядок и перечисление и массив.
Я хотел бы сделать что-то вроде этого:
enum Objects{CAR = 0, PLANE, BOY, size};
const char* texturePaths[Objects::size];
texturePaths[BOY] = "..\\boy.png";
texturePAths[CAR] = "..\\car.png";
...
Я знаю, что это может сработать, но мне нужно сделать это внутри функции и вызвать ее, поэтому время выполнения. Я хочу сделать это во время компиляции, потому что существуют постоянные значения, которые никогда не изменятся, и это бесполезно делать во время выполнения.
Я тоже знаю что constexpr
мог бы сделать это через лямбда-функции, но я не знаю, как это сделать
Вы отметили constexpr
, так что вы можете использовать C ++ 11 или новее, так что вы можете использовать std::array
,
Общее предложение: использовать std::array
, когда это возможно, вместо старых массивов в стиле C.
Я хочу, чтобы так во время компиляции
Если вы принимаете решение C ++ 17 (?), Вы можете использовать тот факт, что неконстантная версия operator[]
за std::array
есть (начиная с C ++ 17) constexpr
,
Таким образом, вы можете создать constexpr
функция для инициализации std::array
как ты хочешь
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;
}
и сохранить результат в constexpr
(важно!) переменная
constexpr auto texturePath { getTexturePath() };
Ниже приводится полный пример компиляции C ++ 17 с некоторыми static_assert()
в качестве доказательства того, что инициализация texturePath
делается во время компиляции.
#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' );
}
Других решений пока нет …