Variadic typedefs, or “Bimaps done the C++0x way”

后端 未结 2 1879
花落未央
花落未央 2021-01-05 04:20

Short question: Can I typedef a variadic argument pack? I need template struct Forward { typedef T... args; };.


Long version

相关标签:
2条回答
  • 2021-01-05 04:59

    You can typedef a tuple. However, I wouldn't know how to then get the types back out again.

    The easiest thing to do would be to just accept two full types.

    0 讨论(0)
  • 2021-01-05 05:09

    You can achieve what you want by encapsulating the variadic argument pack in a tuple and later using the following two helper template structs to forward the actual variadic arguments:

    template<typename PackR, typename PackL>
    struct cat;
    
    template<typename ...R, typename ...L>
    struct cat<std::tuple<R...>, std::tuple<L...>>
    {
            typedef std::tuple<R..., L...> type;
    };
    

    and

    template<typename Pack, template<typename ...T> class Receiver>
    struct Unpack;
    
    template<typename ...Args, template<typename ...T> class Receiver>
    struct Unpack<std::tuple<Args...>, Receiver>
    {
            typedef Receiver<Args...> type;
    };
    

    your code sample would look like this:

    #include <set>
    #include <cstdint>
    #include <tuple>
    
    template<typename PackR, typename PackL>
    struct Cat;
    
    template<typename ...R, typename ...L>
    struct Cat<std::tuple<R...>, std::tuple<L...>>
    {
            typedef std::tuple<R..., L...> type;
    };
    
    template<typename Pack, template<typename ...T> class Receiver>
    struct Unpack;
    
    template<typename ...Args, template<typename ...T> class Receiver>
    struct Unpack<std::tuple<Args...>, Receiver>
    {
            typedef Receiver<Args...> type;
    };
    
    template<typename ...Args>
    struct Forward
    {    
            //typedef Args... args; // Problem here!!
            typedef std::tuple<Args...> args; // Workaround
    
            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;
            typedef typename Unpack<typename Cat<std::tuple<S>, typename SForward::args>::type, SCont>::type left_type; //Workaround
            typedef typename Unpack<typename Cat<std::tuple<T>, typename TForward::args>::type, TCont>::type right_type; //Workaround
    
            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;
    }
    

    which compiles just fine under gcc 4.6.0

    0 讨论(0)
提交回复
热议问题