help needed for specializing a class

A

abir

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 ?
can anyone show how to do it?
(in case anyone wants a compilable code, i had asked it a few days
ago, but hadn't got a solution. I am asking it again with the hope to
get an answer.
The old thread
http://groups.google.co.in/group/co...6ef9b95d7f1f4?lnk=gst&q=abir#5236ef9b95d7f1f4

thanks
abir
 
K

Kai-Uwe Bux

abir said:
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
 
A

abir

abir said:
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. 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
 
K

Kai-Uwe Bux

abir said:
abir said:
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
 
A

abir

abir said:
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.

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
 
A

abir

abir said:
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.

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
 
A

abir

abir said:
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.

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
 
A

abir

abir said:
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.

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
 
A

abir

abir said:
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.

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
 
A

abir

abir said:
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.

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
 
K

Kai-Uwe Bux

abir said:
abir said:
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 ?

What about using overloads:
template< typename C >
class range_v{
public:
typedef typename C::iterator iterator;
typedef typename C::size_type size_type;

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_;

iterator begin() {
return ( begin( static_cast< typename C::is_memorable * >( 0 ) )
);
}


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.

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;
};
}

I don't understand why you insist on putting some flag inside the memorable
containers. You cannot place that flag into standard containers. So what
are you trying to do here? and what is so tricky about specializing a
traits class for the containers you want to be treated as memorable?

If you really want the traits class to detect a memorable_t flag inside the
containers, you can use a detector template:

template < typename T >
class has_memorable_t {

struct yes_type { char dummy; };
struct no_type { yes_type a; yes_type b; };

template < typename S >
static yes_type check ( typename S::memorable_t * );

template < typename S >
static no_type check ( ... );

public:

static bool const value =
( sizeof( check<T>( 0 ) ) == sizeof(yes_type) );

};

and then use has_memorable_t<Container>::value inside some enable_if or so.


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?


Best

Kai-Uwe Bux
 
A

abir

abir said:
abir 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;
};
}

I don't understand why you insist on putting some flag inside the memorable
containers. You cannot place that flag into standard containers. So what
are you trying to do here? and what is so tricky about specializing a
traits class for the containers you want to be treated as memorable?

If you really want the traits class to detect a memorable_t flag inside the
containers, you can use a detector template:

template < typename T >
class has_memorable_t {

struct yes_type { char dummy; };
struct no_type { yes_type a; yes_type b; };

template < typename S >
static yes_type check ( typename S::memorable_t * );

template < typename S >
static no_type check ( ... );

public:

static bool const value =
( sizeof( check<T>( 0 ) ) == sizeof(yes_type) );

};

and then use has_memorable_t said:
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?

Best

Kai-Uwe Bux
I don't know why i had removed enable_if from my specialization (i had
used that in the first post though)
it is working fine now with this definition ,
template<typename C,typename Enable =void>
struct is_memorable {
typedef boost::false_type type;
};
template<typename C>
struct is_memorable<C,typename boost::enable_if<typename
C::memorable>::type > {
typedef boost::true_type type;
};

i am putting memorable tag inside the class because,
1) i want some algo and some function (like begin ) to use that flag,
and i don't need to specialize if for each and every class, rather
specialize for a category of containers ...
2) perhaps more important, i don't know (frankly) how to specialize
the trait for a particular container. ie.
if i have template<typename T, typename Alloc = std::allocator<T> >
my_vector; how to specialize memory_trait for it ? i.e how to
specialize it for a C, where C itself is a template.

however things work now with the overload, and using enable_if (which
i removed for some unknown reason in previous post) to specialize the
trait.

thank you very much... (and sorry for for multiple posts, not sure if
it is a virus or someone refreshed the postdata multiple times when i
was away from desk ) .

abir
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top