specialization of a template function in a template class?!?!?

Discussion in 'C++' started by pookiebearbottom@yahoo.com, Aug 3, 2006.

  1. Guest

    Just trying to learn some things about templates. Was wondering how
    boost::tupple really works, but the headers were a bit confusing to me.
    I know you get do something like the following, just want to know how
    it works with the overloading of get<>().

    boost::tupple<int,double> tup(1,2.0);

    double d=tup.get<2>(); // equal 2.0

    // simple set up,
    template <class T1,class T2> class MyPair
    {
    public:
    T1* m_t1;
    T2* m_t2;
    MyPair(T1* t1,T2* t2)
    : m_t1(t1), m_t2(t2)
    {}

    // want to know how to do this
    template <int J> T1* get() {return m_t1;}

    // just wondering if I could do this
    template <class J> J* get() {return 0;}
    };

    // can I specialize this way?
    template <class T1,class T2> T1* MyPair<T1,T2>::get<1>() { return
    m_t1;}
    template <class T1,class T2> T2* MyPair<T1,T2>::get<2>() { return
    m_t2;}

    // specialized this way??!?!?
    template <class T1,class T2> T1* MyPair<T1,T2>::get<T1>() { return
    m_t1;}
    template <class T1,class T2> T2* MyPair<T1,T2>::get<T2>() { return
    m_t2;}

    thanks
    -sal
     
    , Aug 3, 2006
    #1
    1. Advertising

  2. Alan Johnson Guest

    wrote:
    > Just trying to learn some things about templates. Was wondering how
    > boost::tupple really works, but the headers were a bit confusing to me.
    > I know you get do something like the following, just want to know how
    > it works with the overloading of get<>().
    >
    > boost::tupple<int,double> tup(1,2.0);
    >
    > double d=tup.get<2>(); // equal 2.0
    >
    > // simple set up,
    > template <class T1,class T2> class MyPair
    > {
    > public:
    > T1* m_t1;
    > T2* m_t2;
    > MyPair(T1* t1,T2* t2)
    > : m_t1(t1), m_t2(t2)
    > {}
    >
    > // want to know how to do this
    > template <int J> T1* get() {return m_t1;}
    >
    > // just wondering if I could do this
    > template <class J> J* get() {return 0;}
    > };
    >
    > // can I specialize this way?
    > template <class T1,class T2> T1* MyPair<T1,T2>::get<1>() { return
    > m_t1;}
    > template <class T1,class T2> T2* MyPair<T1,T2>::get<2>() { return
    > m_t2;}
    >
    > // specialized this way??!?!?
    > template <class T1,class T2> T1* MyPair<T1,T2>::get<T1>() { return
    > m_t1;}
    > template <class T1,class T2> T2* MyPair<T1,T2>::get<T2>() { return
    > m_t2;}
    >
    > thanks
    > -sal


    I realize the nature of your question prevents posting compilable code,
    but you should at least try to reduce the errors to the part you are
    asking about. In particular, you need to include
    <boost/tuple/tuple.hpp>, you need to spell tuple correctly (not
    tupple), and get uses a zero based index, so you should be using get<1>
    instead of get<2>.

    Now, to answer your question, you cannot specialize a template unless
    all enclosing templates are totally specialized. Why is this? Beats
    me. I see no good reason for the restriction, but the standard doesn't
    allow it. One thing you may try (a quick glance at tuple's
    implementation suggests boost does something like this) is to create a
    non-member template function, and forward calls to you member function
    to the non-member version. Then specialize the non-member version
    however you like.

    Getting the correct return type for your get function can be tricky.
    The best solution is to create some sort of metafunction that produces
    the correct type for you.

    There is another set of problems to deal with. Particularly, that a
    function cannot be partially specialized (and you would like to
    specialize it based on the types T1 and T2, as well as the return
    type). So, instead of using a non-member function, it may be necessary
    to use a static member of a separate class.

    All put together, it is going to look something like this (I've removed
    your second set of specializations. Consider them an exercise for the
    reader.):

    // Metafunction to help us get the return type.
    template <int N, class T1, class T2>
    struct ReturnTraits ;

    template <class T1, class T2>
    struct ReturnTraits<0, T1, T2>
    {
    typedef T1 ReturnType ;
    } ;

    template <class T1, class T2>
    struct ReturnTraits<1, T1, T2>
    {
    typedef T2 ReturnType ;
    } ;

    // Helper to which we delegate calls to get to get around
    specialization rules.
    template <int N, class ReturnType, class PairType> struct get_class ;

    template <class ReturnType, class PairType>
    struct get_class<0, ReturnType, PairType>
    {
    static ReturnType get(PairType & p)
    {
    p.m_t1 ;
    }
    } ;

    template <class ReturnType, class PairType>
    struct get_class<1, ReturnType, PairType>
    {
    static ReturnType get(PairType & p)
    {
    p.m_t2 ;
    }
    } ;

    // simple set up,
    template <class T1,class T2> class MyPair
    {
    public:
    T1* m_t1;
    T2* m_t2;
    MyPair(T1* t1,T2* t2)
    : m_t1(t1), m_t2(t2)
    {}

    // want to know how to do this
    template <int J>
    typename ReturnTraits<J, T1, T2>::ReturnType * get()
    {
    return get_class<J, typename ReturnTraits<J, T1,
    T2>::ReturnType,
    MyPair<T1, T2> >::get();
    }
    };

    --
    Alan Johnson
     
    Alan Johnson, Aug 3, 2006
    #2
    1. Advertising

  3. Guest

    Alan Johnson wrote:
    > wrote:

    ....

    Thanks for the long answer Alan. FYI, didn't post boost code because I
    know how to use tupple, I wanted to know how the templates worked so I
    could try something similar here.

    Anyway, thanks again for the in-depth answer. Going to take me a while
    to digest it.

    -sal
     
    , Aug 7, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave
    Replies:
    4
    Views:
    7,709
    pdixtl
    Jun 4, 2010
  2. Ruben Campos
    Replies:
    3
    Views:
    6,494
  3. Joseph Turian
    Replies:
    4
    Views:
    608
    John Carson
    Mar 20, 2006
  4. Joseph Turian
    Replies:
    2
    Views:
    480
  5. Replies:
    7
    Views:
    577
Loading...

Share This Page