Short question: Can I typedef a variadic argument pack? I need template <typename ...T> struct Forward { typedef T... args; };
.
Long version:
I was thinking about reimplementing the excellent boost bimap in C++0x. Recall that a bimap of two types S
and T
is a std::set
of relations between S x
and T y
. The objects themselves are stored in two independent internal containers, and the relations track the associated iterators I suppose; both types can serve as keys via "left" and "right" lookup. Depending on the choice of internal containers, values may be unique or not, e.g. if the left container is a set and the right container is a multiset, then one x
can map to many different y
s, and right lookup gives an equal-range. Popular internal containers are set
, multiset
, vector
and list
, and maybe the unordered_*
versions too.
So we need a type which accepts two containers as template parameters:
class Bimap<S, T, std::set, std::multiset>
But we must accept that the containers can take arbitrary many arguments, so we need to pass all those, too. If we just needed one set of variadic arguments, it wouldn't be a problem, since we could pass those directly. But now we need two sets of arguments, so I want to write a forwarder, to be used like so:
Bimap<int, int, std::set, std::set, Forward<std::less<int>, MyAllocator>, Forward<std::greater<int>, YourAllocator>> x;
Here's the template I came up with:
#include <set>
#include <cstdint>
template <typename ...Args>
struct Forward
{
typedef Args... args; // Problem here!!
static const std::size_t size = sizeof...(Args);
};
template <typename S, typename T,
template <typename ...SArgs> class SCont,
template <typename ...TArgs> class TCont,
typename SForward = Forward<>, typename TForward = Forward<>>
class Bimap
{
typedef SCont<S, typename SForward::args> left_type;
typedef TCont<T, typename TForward::args> right_type;
template <typename LeftIt, typename RightIt> struct Relation; // to be implemented
typedef Relation<typename left_type::const_iterator, typename right_type::const_iterator> relation_type;
};
int main()
{
Bimap<int, int, std::set, std::set, Forward<std::less<int>>, Forward<std::greater<int>>> x;
}
Unfortunately, in the indicated line in Forward
I cannot figure out how to typedef the parameter pack! (The commented line gives a compiler error.)
[I suppose I could go for a lazy version Bimap<std::set<int, MyPred>, std::multiset<char, YourPred>> x;
and extract the types via LeftCont::value_type
and RightCont::value_type
, but I thought it'd be nicer if I could make the key types my primary template arguments and allow defaulting to std::set
containers.]