specialize template member function of a template class

Discussion in 'C++' started by toton, Jan 24, 2007.

  1. toton

    toton Guest

    Hi,
    I want to specialize template member function of a template class .
    It is creating some syntax problem ....
    Can anyone say how to do it ?

    The class is something like this
    template<typename T,typename Alloc = std::allocator<T> >
    class CircularBuffer4 {
    public:
    typedef typename CircularBuffer<T,Alloc>::size_type
    size_type;
    private:
    CircularBuffer<T,Alloc> x_;
    CircularBuffer<T,Alloc> y_;
    CircularBuffer<T,Alloc> xd_;
    CircularBuffer<T,Alloc> yd_;
    template<DirectionType dt> const CircularBuffer<T,Alloc>& buf()const;
    }
    where
    enum DirectionType{
    dtX,dtY
    };
    I want to specialize buf for dtX & dtY

    template<typename T,typename Alloc>
    template<>const CircularBuffer<T,Alloc>&
    CircularBuffer4<T,Alloc>::buf<dtX>()const{
    return x_;
    }
    This does not compile,
    but,
    template<typename T,typename Alloc>
    template<DirectionType dt>const CircularBuffer<T,Alloc>&
    CircularBuffer4<T,Alloc>::buf()const{
    return x_;
    }
    this compiles ....
    In both cases all of the codes are in header (I hadn't made the
    specialized template code in a cpp file, hope that doesn't cause
    problem)

    thanks in advance
    abir
     
    toton, Jan 24, 2007
    #1
    1. Advertising

  2. toton wrote:
    > I want to specialize template member function of a template class .
    > It is creating some syntax problem ....
    > Can anyone say how to do it ?


    In order to specialise a member you _must_ specialise the class first.

    > The class is something like this
    > template<typename T,typename Alloc = std::allocator<T> >
    > class CircularBuffer4 {
    > public:
    > typedef typename CircularBuffer<T,Alloc>::size_type
    > size_type;
    > private:
    > CircularBuffer<T,Alloc> x_;
    > CircularBuffer<T,Alloc> y_;
    > CircularBuffer<T,Alloc> xd_;
    > CircularBuffer<T,Alloc> yd_;
    > template<DirectionType dt> const CircularBuffer<T,Alloc>& buf()const;
    > }
    > where
    > enum DirectionType{
    > dtX,dtY
    > };
    > I want to specialize buf for dtX & dtY


    Why? How would you use it? Couldn't you simply have two functions,
    one named 'buf_dtX' and the other 'buf_dtY'?

    > template<typename T,typename Alloc>
    > template<>const CircularBuffer<T,Alloc>&
    > CircularBuffer4<T,Alloc>::buf<dtX>()const{
    > return x_;
    > }
    > This does not compile,
    > but,
    > template<typename T,typename Alloc>
    > template<DirectionType dt>const CircularBuffer<T,Alloc>&
    > CircularBuffer4<T,Alloc>::buf()const{
    > return x_;
    > }
    > this compiles ....


    Because it's not a specialisation. It's just the definition.

    > In both cases all of the codes are in header (I hadn't made the
    > specialized template code in a cpp file, hope that doesn't cause
    > problem)


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jan 24, 2007
    #2
    1. Advertising

  3. toton

    toton Guest

    On Jan 24, 7:25 pm, "Victor Bazarov" <> wrote:
    > toton wrote:
    > > I want to specialize template member function of a template class .
    > > It is creating some syntax problem ....
    > > Can anyone say how to do it ?In order to specialise a member you _must_ specialise the class first.

    >
    >
    >
    > > The class is something like this
    > > template<typename T,typename Alloc = std::allocator<T> >
    > > class CircularBuffer4 {
    > > public:
    > > typedef typename CircularBuffer<T,Alloc>::size_type
    > > size_type;
    > > private:
    > > CircularBuffer<T,Alloc> x_;
    > > CircularBuffer<T,Alloc> y_;
    > > CircularBuffer<T,Alloc> xd_;
    > > CircularBuffer<T,Alloc> yd_;
    > > template<DirectionType dt> const CircularBuffer<T,Alloc>& buf()const;
    > > }
    > > where
    > > enum DirectionType{
    > > dtX,dtY
    > > };
    > > I want to specialize buf for dtX & dtY

    "Why? How would you use it? Couldn't you simply have two functions,"
    Yes, two function is definitely possible. Just wanted to add little
    "sugar" to it.
    I have a templated function operate, which operates on dtX & dtY. Both
    are called, always.
    Thus either I have to write 2 operate functions, or generate 2, if I
    dont want to use if else ....
    So I generated. Now once operate is generated, I need have template
    member as all of these class which it calls, again to avoid if else.

    The code flow is something like this (all classes are not defined, but
    surely one will get the flow).
    void SegmentOperator::eek:perate(store::CC& cc) {
    cc_ = &cc;
    store::ConstPointRange points = cc.points();
    operate<dtX>(points);
    operate<dtY>(points);
    operate<dtXD>(points);
    operate<dtYD>(points);
    }
    well, I could have written 4 functions instead of generating, or a
    single function with a if -else or switch statement.

    each template are something like,
    template<DirectionType dt>void
    SegmentOperator::eek:perate(store::ConstPointRange& points) {
    size_t size = points.size();
    //Current CC reconstructed Points.
    Range range(0,size);
    //check the No. of points in CC.
    //if No. of points less than 2 than nothing to do.
    if (size < 2) {
    cc_->addSegment<dt>(store::Segment(cc_,range,stDot));
    return;
    }
    ///blah blah blah...
    }
    Here ConstPointRange is a boost::sub_range (a pair of iterators) ,
    Range is typedef of std::pair, Segment & CC are my specialized class.
    Here as all of the operations are done in 4 directions always,
    sometimes 4 specialization, but mostly through simple template ...
    That avoids a switch and throw at default value (a runtime check) , and
    makes sure all of the parameters passed as direction are proper.
    Now once this is templated, whatever it calls can be templated also.
    Like I can write a if with addSegment_x, addSegment_y etc, or even
    addSegment(DirectionType dt) . In all cases if-else or switch with
    throw is there.

    Now it also stores 4 directional data , in form of vector4 or
    circular_buffer4 , and each operator needs to take the appropriate
    data.
    Of course each of the type for the container is specified, using
    typedef like typedef PointVector4 Vector4<Point> , but I thought to
    implement the templated member for vector4 instead, and use if for all
    PointVector4, VelocityVector4 etc.

    At present I have a switch at the templated classes, with non
    templated member function, but for a non templated class a templated
    member function.
    I have a bunch of Vector4 classes which are typedef. If I want to
    specialize all of them, it will again cause repetition. Rather I want
    to tell the compiler that these typedefs are specialization, and make
    the 4 template member function for only those typedefs.

    I hope, it says my problem to some extent.
    Thanks for pleasant listening ....
    looking for some advice.

    abir


    > one named 'buf_dtX' and the other 'buf_dtY'?
    >
    > > template<typename T,typename Alloc>
    > > template<>const CircularBuffer<T,Alloc>&
    > > CircularBuffer4<T,Alloc>::buf<dtX>()const{
    > > return x_;
    > > }
    > > This does not compile,
    > > but,
    > > template<typename T,typename Alloc>
    > > template<DirectionType dt>const CircularBuffer<T,Alloc>&
    > > CircularBuffer4<T,Alloc>::buf()const{
    > > return x_;
    > > }
    > > this compiles ....Because it's not a specialisation. It's just the definition.

    >
    > > In both cases all of the codes are in header (I hadn't made the
    > > specialized template code in a cpp file, hope that doesn't cause
    > > problem)V

    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask
     
    toton, Jan 25, 2007
    #3
  4. toton wrote:
    > On Jan 24, 7:25 pm, "Victor Bazarov" <> wrote:
    >> toton wrote:
    >>> I want to specialize template member function of a template class .
    >>> It is creating some syntax problem ....
    >>> Can anyone say how to do it ?In order to specialise a member you
    >>> _must_ specialise the class first.

    [...]

    Take a look at this, maybe it will help.

    template<class T> struct A
    {
    void func1(int) const;
    void func2(int) const;

    enum e { one, two, three, four, five };

    typedef std::map<e, void (A::*)(int) const > funcmap_t;
    static funcmap_t mapping;
    static int dummy_mapping_initialiser;
    static int doit() {
    mapping.insert(make_pair(one, &A::func1));
    mapping.insert(make_pair(two, &A::func2));
    }

    void call_it(e ee, int i) {
    (this->*(mapping[ee]))(i);
    }

    public:
    A() {}
    void operate(int);
    };

    template<class T> std::map<e, void (A<T>::*)(int) const > A<T>::mapping;
    template<class T> int A<T>::dummy_mapping_initiliaser = A<T>::doit();

    template<class T> void A<T>::eek:perate(int blah) {
    typename funcmap_t::iterator it = mapping.begin(), e =
    mapping.end();
    while (it != e) {
    call_it(it->first, blah);
    ++it;
    }
    }

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jan 25, 2007
    #4
    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. Peter Koch Larsen

    How to specialize member template function?

    Peter Koch Larsen, Jan 25, 2005, in forum: C++
    Replies:
    9
    Views:
    473
    Peter Koch Larsen
    Jan 25, 2005
  2. mrstephengross
    Replies:
    1
    Views:
    288
    Victor Bazarov
    Aug 2, 2005
  3. Replies:
    1
    Views:
    361
    Victor Bazarov
    Feb 17, 2006
  4. Imre
    Replies:
    2
    Views:
    337
    mlimber
    May 25, 2006
  5. Replies:
    16
    Views:
    589
    Victor Bazarov
    Mar 15, 2007
Loading...

Share This Page