Re: help needed for specializing a class
On Apr 1, 11:29 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
abir wrote:
On Apr 1, 6:10 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
abir wrote:
hi,
I have a template (partial code only to express the intent)
The class have many other functions & typedefs.
template<typename C>
class range_v{
public:
typedef typename C::iterator iterator;
typedef typename C::size_type size_type;
public:
iterator begin(){
return cont_->begin()+begin_;
}
iterator end(){
return cont_->begin()+end_;
}
private:
C* cont_;
size_type begin_;
size_type end_;
};
I want to specialize it for some C , only for begin and like,
template<typename C,typename boost::enable_if<typename
C::is_memorable>::type >
class range_v{
public:
typedef typename C::iterator iterator;
typedef typename C::size_type size_type;
public:
iterator begin(){
return cont_->begin()+begin_ - cont_->remove_count();
}
iterator end(){
return cont_->begin()+end_- cont_->remove_count();
}
private:
C* cont_;
size_type begin_;
size_type end_;
};
where the original definition changed to
template<typename C,typename Enable = void> class range_v;
so basically, if the container C has a trait as memorable , i subtract
remove_count from begin & end. But all of other member functions (not
shown here ) are same.
is it possible to specialize ONLY these two functions rather than the
full class ?
[snip]
What about using overloads:
template< typename C >
class range_v{
public:
typedef typename C::iterator iterator;
typedef typename C::size_type size_type;
private:
iterator begin ( yes_type * ) {
return cont_->begin()+begin_ - cont_->remove_count();
}
iterator begin ( no_type * ) {
return cont_->begin()+begin_;
}
C* cont_;
size_type begin_;
size_type end_;
public:
iterator begin() {
return ( begin( static_cast< typename C::is_memorable * >( 0 ) ) );
}
};
Best
Kai-Uwe Bux
I thought about the overloading a few times. But the problem is i want
some additional behavior for begin & end (which subtracts remove_count
for a remove aware containers) . However std containers doesn't define
that trait. it is me who has defined it. so it C is a std::vector ,
typename C::is_memorable is not available, hence it will fail to work
with std containers.
Well, then define a traits template:
template < typename Container >
struct memorable_trait {
static const bool value = false;
typedef no_type type;
};
and specialize it for the containers you want.
Then you can overload on
memorable_trait<C>::type *
inside range_v.
so in some way i need to introduce a template
definition of begin & end so that when C::is_memorable is not
available , it will remove the definition from the overload, which is
not possible for plain member function overloads.
however i am not finding a way to auto deduce typename for member
functions (i can do that for free standing function like boost::begin
overload however) , also i am not finding a way to apply default
argument for member function template , like i can do in class
function template.
So i opted for a full class specialization.
However still i _think_ that it can be done with either member
function template or inheritance (i.e using CRTP) without copy-pasting
the code twice for the class.
thanks
abir
Exactly this is what i was looking for ...
But i was thinking in terms of template specialization
many thanks for the an
Best
Kai-Uwe Bux
Thanks,
the idea i had implemented a few moments ago like this, ...
template<typename C,typename Enable =void>
struct is_memorable{
typedef boost::false_type type;
};
template<typename C>
struct is_memorable<C,typename C::memorable>{
typedef boost::true_type type;
};
where for a memorable container it is like
namespace vec{
template<typename T>
class memory_vector{
private:
struct memorable_t;
public:
typedef memorable_t memorable;
};
}
but it looks, that the compiler always takes the false definition,
instead of the specialization.
so i think, in some ways, it is the definition which is unavailable to
the compiler.
can u specify in which namespace i will put the definitions ?
like for each memorable container will i put the specialization there
(and one in std namespace with false_type ) ?
in which order compiler searches for these definitions?
thanks
abir