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>{}();
}
You have several issues:
Your specialization doesn't match your primary template
template <int N, typename T1, typename T2, typename ...Ts> struct Recursive;
requires at least 3 parameters. I think it should be a specialization and primary template should be:template <int N, typename T> struct Recursive<N, T>
doesn't behave like astd::pair
(as you state your requirement, else your usage is wrong), you probably want something like:You need to "forward" the constructors of the base class, (Composition instead of inheritance might be an option too, or traits to define type to use) or change way to construct the object.
Result is:
Demo