My target is to define a Recursive
class, templated on an int N
and one or more types T, ...Ts
, which should behave like a std::pair
with
- a
std::array
ofN
items of typeT
as thefirst
, - and, as
second
, an optionalstd::vector
ofRecursive
instances templated on the sameN
and on the remaining template argumentsTs...
.
In trying to write down the class given the above requirements, I've come up with this non-working code (where I've also defined some necessary, as they help a lot, aliases for two instantiations of Recursive
), and I don't know if I have mis-designed what I described above (or if it is an ill-formed description!), or if I'm misusing the language syntax.
#include <array>
#include <boost/hana/fwd/optional.hpp>
#include <boost/hana/optional.hpp>
#include <string>
#include <utility>
#include <vector>
template <int N, typename T1, typename T2, typename ...Ts>
struct Recursive
: std::pair<std::array<T1, N>,
boost::hana::optional<std::vector<Recursive<N, T2, Ts...>>>> {};
template <int N, typename T>
struct Recursive<N, T> : std::array<T, N> {};
template<typename ...T>
using Recursive2 = Recursive<2u, T...>;
template<typename ...T>
using Recursive3 = Recursive<3u, T...>;
int main() {
using boost::hana::nothing;
Recursive2<int> x(std::make_pair(std::array<int, 2>{0,0}, nothing));
}
I'll add some troubleshooting that I've done so far. In the following the template specilization seems to work just fine.
#include <iostream>
template <int N, typename T, typename ...Ts>
struct Recursive {
void operator()(){ std::cout << "general\n"; }
};
template <int N, typename T>
struct Recursive<N, T> {
void operator()(){ std::cout << "specialized\n"; }
};
template<typename ...T>
using Recursive2 = Recursive<2u, T...>;
template<typename ...T>
using Recursive3 = Recursive<3u, T...>;
int main() {
Recursive2<int>{}();
Recursive2<int>{}();
Recursive2<int,int>{}();
}