Как реализовать метод получения времени компиляции для более краткого вызова?

Я хочу реализовать метод получения времени компиляции таким образом, чтобы сделать его вызов более лаконичным. У меня нетип типа (unsigned int N) шаблон класса foo, который рекурсивно наследует от foo<N - 1>, каждый foo имеет свой enum член называется number, который инициализируется значением соответствующего N, Базовый случай foo<0>, Например, foo<5> Объект имеет 6 enumназывается numberценится 0 через 5, Я хочу реализовать компилятор времени компиляции at, но это не так просто, как подготовить constexpr к прототипу:

template <unsigned int N>
struct foo : protected foo<N - 1> {
protected:
enum {number = N};
public:
constexpr int const& at(const unsigned int index) {
static_assert(index <= N, "out of range");
return this->foo<index>::number;
}
};

template <>
struct foo<0> {
protected:
enum {number = 0};
public:
constexpr int const& at(const unsigned int index) {
static_assert(index == 0, "out of range");
return this->number;
}
};

В g ++ 4.8 я получаю несколько примеров ошибок: error: 'index' is not a constant expressionкроме всего прочего. Остальные просто следуют примеру. Даже если все вызовы кода клиента at только с целочисленными литералами геттер не будет компилироваться. Зачем?

В любом случае, моим решением было реализовать целочисленную обертку во время компиляции. Это просто не тип (unsigned int N) шаблон класса ctint (сокращение от int во время компиляции), чьи enum член mem инициализируется к его N:

template <unsigned int N>
struct ctint {
enum {mem = N};
};

Итак, замена foo<N> а также foo<0>Методы получения, соответственно, с:

template <unsigned int ind>
constexpr int const& at(ctint<ind> const& ctint_par) {
static_assert(ctint_par.mem <= N, "out of range");
return this->foo<ctint_par.mem>::number;
}

а также

template <unsigned int ind>
constexpr int const& at(ctint<ind> const& ctint_par) {
static_assert(ctint_par.mem == 0, "out of range");
return this->number;
}

работает:

int main() {
foo<5> f;
static_assert( f.at( ctint<4>{} ) != 4 , "equals 4");
}

но делает вызов функции многословным. Мне нужна реализация, которая не содержит библиотек, кроме отдельных частей (например, <iostream>), которые показывают что-то работает, но не помогают заставить это работать. Я хотел бы, чтобы получатель мог опционально опускать или не иметь <> синтаксис или написание имени типа в вызове, но не обязательно в прототипе или определении. Я не хочу вовлекать array[]s. Если это невозможно, я бы хотел узнать следующий лучший способ.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …