By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,411 Members | 1,037 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,411 IT Pros & Developers. It's quick & easy.

specialize template member function of a template class

P: n/a
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,Allocx_;
CircularBuffer<T,Allocy_;
CircularBuffer<T,Allocxd_;
CircularBuffer<T,Allocyd_;
template<DirectionType dtconst 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

Jan 24 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
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,Allocx_;
CircularBuffer<T,Allocy_;
CircularBuffer<T,Allocxd_;
CircularBuffer<T,Allocyd_;
template<DirectionType dtconst 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
Jan 24 '07 #2

P: n/a


On Jan 24, 7:25 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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,Allocx_;
CircularBuffer<T,Allocy_;
CircularBuffer<T,Allocxd_;
CircularBuffer<T,Allocyd_;
template<DirectionType dtconst 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::operate(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::operate(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
Jan 25 '07 #3

P: n/a
toton wrote:
On Jan 24, 7:25 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>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 Tstruct 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 Tstd::map<e, void (A<T>::*)(int) const A<T>::mapping;
template<class Tint A<T>::dummy_mapping_initiliaser = A<T>::doit();

template<class Tvoid A<T>::operate(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
Jan 25 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.