I'll dump the code first, adding references and comments where necessary/appropriate later. Just leave a comment if the result is somewhat close to what you're looking for.
Indices trick for pack expansion (required here to apply the generator), by Xeo, from this answer, modified to use std::size_t instead of unsigned.
#include <cstddef> // by Xeo, from https://stackoverflow.com/a/13294458/420683 template<std::size_t... Is> struct seq{}; template<std::size_t N, std::size_t... Is> struct gen_seq : gen_seq<N-1, N-1, Is...>{}; template<std::size_t... Is> struct gen_seq<0, Is...> : seq<Is...>{};
Generator function:
#include <array> template<class Generator, std::size_t... Is> constexpr auto generate_array_helper(Generator g, seq<Is...>) -> std::array<decltype(g(std::size_t{}, sizeof...(Is))), sizeof...(Is)> { return {{g(Is, sizeof...(Is))...}}; } template<std::size_t tcount, class Generator> constexpr auto generate_array(Generator g) -> decltype( generate_array_helper(g, gen_seq<tcount>{}) ) { return generate_array_helper(g, gen_seq<tcount>{}); }
Usage example:
// some literal type struct point { float x; float y; }; // output support for `std::ostream` #include <iostream> std::ostream& operator<<(std::ostream& o, point const& p) { return o << p.x << ", " << p.y; } // a user-defined generator constexpr point my_generator(std::size_t curr, std::size_t total) { return {curr*40.0f/(total-1), curr*20.0f/(total-1)}; } int main() { constexpr auto first_array = generate_array<5>(my_generator); constexpr auto second_array = generate_array<10>(my_generator); std::cout << "first array: \n"; for(auto p : first_array) { std::cout << p << '\n'; } std::cout << "========================\n"; std::cout << "second array: \n"; for(auto p : second_array) { std::cout << p << '\n'; } }
std::vectoris not a literal type and therefore cannot be used in C++11constexpr. C++11'sarraytype lacksconstexpraccessors and therefore also has limited use inconstexprfunctions. If you don't have some of the C++1y lib/compiler support, I suggest using a custom array type instead.initializer_list, as they're required to be literal types in C++1y.