Я пытаюсь сделать простой способ генерации std::array
во время компиляции. До сих пор это была борьба за то, чтобы найти хороший способ передать функцию constexpr во время компиляции. Обходной путь, который я нашел до сих пор, выглядит следующим образом.
#include <iostream>
#include <array>
namespace a {
constexpr int f(const int & i) { return i * i * i;}
#include "generate_with_function.hpp"
}
int main()
{
auto arr = a::generator<false,10,0>::array;
for (auto i : arr) {
std::cout << i << " ";
}
return 0;
}
это в основном предполагает, что вы определите функцию, называемую f
и я завернул ее в пространство имен, я хотел бы сделать другое. Я хотел знать, есть ли более умный способ передать функцию и использовать ее во время компиляции. Также здесь приведен код, который составляет список.
template <bool B, size_t Count,int ... Nums>
struct generator;
template <size_t Count>
struct generator<false,Count,0>
{
constexpr static std::array<int,Count> array
= generator<false,Count,1,f(0)>::array;
};
template <size_t Count, int Current, int ... Results>
struct generator<false,Count,Current, Results...>
{
constexpr static std::array<int,Count> array
= generator<Current+1==Count,Count,Current+1,f(Current), Results...>::array;
};
template <size_t Count, int Current, int ... Results>
struct generator<true,Count,Current,Results...>
{
constexpr static std::array<int,Count> array{{Results...}};
};
и прежде чем вы спросите, у меня нет реальной потребности в этом.
Как отмечалось в @us2012, я должен быть конкретным относительно того, что я бы предпочел.
Фактически вы можете использовать функцию в качестве параметра шаблона, называемого Gen
:
template <bool B, size_t Count, int Current, int Gen(size_t), int ... Nums>
struct generator;
template <size_t Count, int Current, int Gen(size_t), int ... Results>
struct generator<false,Count,Current, Gen, Results...>
{
constexpr static std::array<int,Count> array
generator<Current+1==Count,Count,Current+1,Gen,
Gen(Current), Results...>::array;
};
template <size_t Count, int Current, int Gen(size_t), int ... Results>
struct generator<true,Count,Current,Gen,Results...>
{
constexpr static std::array<int,Count> array{{Results...}};
};
При этом он фактически выполняет передачу функции constexpr в шаблон (если тип точно соответствует):
// helper to hide the "internal" template parameters
template <size_t Count, int Gen(size_t)>
struct gen {
constexpr static std::array<int, Count> array = generator<false, Count, 0, Gen>::array;
};
constexpr int f(size_t i) { return i * i * i; }
int main()
{
auto arr = gen<10,f>::array;
for (auto i : arr) {
std::cout << i << " ";
}
return 0;
}
Вы также можете переключать параметры Gen(Current)
и Results...
чтобы получить значения в "правильных" индексах массива.
size_t
, но, вероятно, ее можно обобщить, добавив еще один параметр шаблона для типа параметра функции или около того.