I apologize already having asked a similar question here when I should have modified the question I asked first.
I have the class Level which constructor requires an argument.
Using variadic templates I create a type LevelType for a member of the class Tree which is a tuple of elements of type Level.
How can I avoid repeating the value data in the initialization list of Tree?
As a further constraint, it should be possible for objects of class Tree to be constructed at compile time, so as far as I know I need some kind of template metaprogramming-fu.
Thank you!
Here's a code snippet:
#include<utility>
#include<array>
#include<iostream>
class LevelData
{};
template <typename LevelType>
class Level
{
public:
Level(LevelData & data_):
data(data_)
{};
LevelData & data ;
};
template <std::size_t nLevels,typename LevelType>
class Tree
{
public:
Tree(LevelData & data):
level(data,data,data,data,data)
{};
LevelType level ;
};
template <std::size_t nLevels,auto... Is>
auto make_tree_impl(std::index_sequence<Is...>)
-> Tree<nLevels,std::tuple<Level<std::array<double, std::size_t{1} << Is>>...>>;
template <std::size_t nLevels>
using make_tree = decltype(make_tree_impl<nLevels>(std::make_index_sequence<nLevels>{}));
int main()
{
const unsigned int nLevels = 5;
LevelData data;
auto tree = make_tree<nLevels>(data);
std::cout << std::is_same<decltype(tree),
Tree<nLevels,std::tuple<Level<std::array<double,1>>,
Level<std::array<double,2>>,
Level<std::array<double,4>>,
Level<std::array<double,8>>,
Level<std::array<double,16>>>>>::value << std::endl ;
return 0;
}
You could make use of
make_index_sequenceagain, only this time it's used to repeatdataas many times as you have types in yourtuple.Unfolding can be done by using
(static_cast<void>(Is), data)...since the left part of the,operator will be discarded, leaving onlydata,sizeof...(Is)number of times.