matching multiple template

A

abir

i have a template
template<typename S> class Indexer{};
i want to have a specialization for std::vector both const & non const
version.
template<typename T,typename A> class Indexer<std::vector<T,A> > {}
matches only with nonconst version. anyway to match it for both? and
get if it is const or nonconst?

Actually i want 2 specialization, one for std::vector<T,A> const & non
const other for std::deque<T,A> const & non const.

thanks
abir
 
E

Eric Pruneau

abir said:
i have a template
template<typename S> class Indexer{};
i want to have a specialization for std::vector both const & non const
version.
template<typename T,typename A> class Indexer<std::vector<T,A> > {}
matches only with nonconst version. anyway to match it for both? and
get if it is const or nonconst?

Actually i want 2 specialization, one for std::vector<T,A> const & non
const other for std::deque<T,A> const & non const.

thanks
abir

I'm not sure if I understand what you really want to do but here is what I
think.

you have a class

template<typename S>
class Indexer{ };

and you want to specialize this class when S is a vector and when S is a
const vector (samething with deque).

Here is how to do that. Note that I've removed the allocator template
parameter to simplify the example but I amsure you will find a way to
integrate it!!!


template<typename T, typename CONT>
struct Indexer
{
Indexer() { cout <<"1\n"; }
};

template<typename T>
struct Indexer<T, vector<T> >
{
Indexer() { cout <<"2\n"; }
};

template<typename T>
struct Indexer<T, const vector<T> >
{
Indexer() { cout <<"3\n"; }
};

template<typename T>
struct Indexer<T, deque<T> >
{
Indexer() { cout <<"4\n"; }
};

template<typename T>
struct Indexer<T, const deque<T> >
{
Indexer() { cout <<"5\n"; }
};


int main()
{
Indexer<int, vector<int> > a; // print 2
Indexer<int, deque<int> > b; // print 4
Indexer<int, vector<int> const > c; // print 3
Indexer<int, deque<int> const > d; // print 5

return 0;
}
 
A

abir

I'm not sure if I understand what you really want to do but here is what I
think.

you have a class

template<typename S>
class Indexer{ };

and you want to specialize this class when S is a vector and when S is aconstvector (samething with deque).

Here is how to do that. Note that I've removed the allocatortemplate
parameter to simplify the example but I amsure you will find a way to
integrate it!!!

template<typename T, typename CONT>
struct Indexer
{
Indexer() { cout <<"1\n"; }

};

template<typename T>
struct Indexer<T, vector<T> >
{
Indexer() { cout <<"2\n"; }

};

template<typename T>
struct Indexer<T,constvector<T> >
{
Indexer() { cout <<"3\n"; }

};

template<typename T>
struct Indexer<T, deque<T> >
{
Indexer() { cout <<"4\n"; }

};

template<typename T>
struct Indexer<T,constdeque<T> >
{
Indexer() { cout <<"5\n"; }

};

int main()
{
Indexer<int, vector<int> > a; // print 2
Indexer<int, deque<int> > b; // print 4
Indexer<int, vector<int>const> c; // print 3
Indexer<int, deque<int>const> d; // print 5

return 0;

}

Thanks for answering.
Actually this is what i have already. What i want is to match both
const & non const version in same specialization something like (this
is not a valid syntax of course),
template<typename T>
struct Indexer<T,const vector<T> | vector<T> >
{
Indexer() { cout <<"3\n"; }

};
so i want both the match to succeed in same specialization. Also i
need to know which match is there.
i don't know if it is directly possible, but i am thinking having a
proxy class to delegate the responsibility.

thanks
abir
 
E

Eric Pruneau

[...]
Thanks for answering.
Actually this is what i have already. What i want is to match both
const & non const version in same specialization something like (this
is not a valid syntax of course),
template<typename T>
struct Indexer<T,const vector<T> | vector<T> >
{
Indexer() { cout <<"3\n"; }

};
so i want both the match to succeed in same specialization. Also i
need to know which match is there.
i don't know if it is directly possible, but i am thinking having a0
proxy class to delegate the responsibility.

thanks
abir

Ok you leave me no choice but to use the big guns!!!

here is a solution using boost type triats and enable_if

template<typename T, typename CONT, typename enable=void>
struct Indexer
{
Indexer() { cout <<"1\n"; }
};

// this one could be a bit scary....

template<typename T, typename CONT>
struct Indexer<T, CONT, typename boost::enable_if_c<boost::is_same<
typename boost::add_const said:
{
Indexer() { cout <<"2\n"; }
};


int main()
{
Indexer<int, vector<int> > a; // print 2
Indexer<int, const vector<int> > b; // guess what? it prints 2 !!!
Indexer<int, deque<int> > c; // print 1
return 0;
}

ok here is the trick

add_const<CONT>::type just add a const before CONT if CONT is not already
const. it does nothing if CONT is already const.

then we do:
is_same<const CONT, const vector<T> >::value
this returns true if const CONT = const vector<T>

finally enable_if_c has 2 template parameter (the second is void by default)
The first one must be a bool
enable_if_c<true>::type return void
enable_if_c<false>::type is an error

so if
is_same<const CONT, const vector<T> >::value
returns true we got a match and the second template Indexer is used.
if const CONT is not a const vector then the first template Indexer is used.

you can find the boost library here www.boost.org
It is a must . If you don't have it, get it!
 
A

abir

[...]


Thanks for answering.
Actually this is what i have already. What i want is to match both
const & non const version in same specialization something like (this
is not a valid syntax of course),
template<typename T>
struct Indexer<T,const vector<T> | vector<T> >
{
Indexer() { cout <<"3\n"; }
};
so i want both the match to succeed in same specialization. Also i
need to know which match is there.
i don't know if it is directly possible, but i am thinking having a0
proxy class to delegate the responsibility.
thanks
abir

Ok you leave me no choice but to use the big guns!!!

here is a solution using boost type triats and enable_if

template<typename T, typename CONT, typename enable=void>
struct Indexer
{
Indexer() { cout <<"1\n"; }

};

// this one could be a bit scary....

template<typename T, typename CONT>
struct Indexer<T, CONT, typename boost::enable_if_c<boost::is_same<
{
Indexer() { cout <<"2\n"; }

};

int main()
{
Indexer<int, vector<int> > a; // print 2
Indexer<int, const vector<int> > b; // guess what? it prints 2 !!!
Indexer<int, deque<int> > c; // print 1
return 0;

}

ok here is the trick

add_const<CONT>::type just add a const before CONT if CONT is not already
const. it does nothing if CONT is already const.

then we do:
is_same<const CONT, const vector<T> >::value
this returns true if const CONT = const vector<T>

finally enable_if_c has 2 template parameter (the second is void by default)
The first one must be a bool
enable_if_c<true>::type return void
enable_if_c<false>::type is an error

so if
is_same<const CONT, const vector<T> >::value
returns true we got a match and the second template Indexer is used.
if const CONT is not a const vector then the first template Indexer is used.

you can find the boost library here www.boost.org
It is a must . If you don't have it, get it!

This is nearly what i wanted. But with a little difference. like this
one.
int main()
{
Indexer<vector<int> > a; // print 2
Indexer<const vector<int> > b; // guess what? it prints 2 !!!
Indexer<deque<int> > c; // print 1
return 0;
}
i.e without the first int (and the alloc param if any). otherwise it
is fine to me.
i use boost & tr1 so know enable_if & remove_const etc.
can is_same compare templates rather than types ? then i can pass the
first arg as template <typename T,typename A> class S and make
comparison with std::vector ? Or can i put T at last to meke auto
deduction of type T without specifying it?

thanks for answering
abir


Thanks for reply. I was unable to see my post for long hours, so i had
posted the same once again, in this thread
http://groups.google.com/group/comp...99/fb1ca1a6f5ae69b5?lnk=raot#fb1ca1a6f5ae69b5
where i explained my intension also.
 
A

abir

[...]


Thanks for answering.
Actually this is what i have already. What i want is to match both
const & non const version in same specialization something like (this
is not a valid syntax of course),
template<typename T>
struct Indexer<T,const vector<T> | vector<T> >
{
Indexer() { cout <<"3\n"; }
};
so i want both the match to succeed in same specialization. Also i
need to know which match is there.
i don't know if it is directly possible, but i am thinking having a0
proxy class to delegate the responsibility.
thanks
abir

Ok you leave me no choice but to use the big guns!!!

here is a solution using boost type triats and enable_if

template<typename T, typename CONT, typename enable=void>
struct Indexer
{
Indexer() { cout <<"1\n"; }

};

// this one could be a bit scary....

template<typename T, typename CONT>
struct Indexer<T, CONT, typename boost::enable_if_c<boost::is_same<
{
Indexer() { cout <<"2\n"; }

};

int main()
{
Indexer<int, vector<int> > a; // print 2
Indexer<int, const vector<int> > b; // guess what? it prints 2 !!!
Indexer<int, deque<int> > c; // print 1
return 0;

}

ok here is the trick

add_const<CONT>::type just add a const before CONT if CONT is not already
const. it does nothing if CONT is already const.

then we do:
is_same<const CONT, const vector<T> >::value
this returns true if const CONT = const vector<T>

finally enable_if_c has 2 template parameter (the second is void by default)
The first one must be a bool
enable_if_c<true>::type return void
enable_if_c<false>::type is an error

so if
is_same<const CONT, const vector<T> >::value
returns true we got a match and the second template Indexer is used.
if const CONT is not a const vector then the first template Indexer is used.

you can find the boost library here www.boost.org
It is a must . If you don't have it, get it!

oh concern to my last post about how to get rid of the extra int ,
i was stupid enough to forget that CONT::value_type is T,
so my final version is

template<typename S,typename enable = void>
class Indexer;

template<typename S>
class Indexer<S,typename boost::enable_if_c<std::tr1::is_same<
typename std::tr1::add_const<S>::type, const
std::vector<typename S::value_type,typename
S::allocator_type>>::value>::type
public:
typedef Indexer<S> self_type;
typedef Indexer<typename std::tr1::remove_const<S>::type>
nonconst_self;
public:
Indexer(S& s) {
std::cout<<"vec ctor\n";
}
Indexer(nonconst_self& s){
std::cout<<"vec copy\n";
}
};
template<typename S>
class Indexer<S,typename boost::enable_if_c<std::tr1::is_same<
typename boost::add_const<S>::type, const
std::deque<typename S::value_type,typename
S::allocator_type>>::value>::type
public:
typedef Indexer<S> self_type;
typedef Indexer<typename std::tr1::remove_const<S>::type>
nonconst_self;
public:
Indexer(S& s) {
std::cout<<"deq ctor\n";
}
Indexer(nonconst_self& s){
std::cout<<"deq copy\n";
}
};

and calling syntax is
typedef std::vector<int> VI;
VI v;
Indexer<VI> I1(v);
Indexer<const VI> I2(v);
Indexer<const VI> I3(cv);
//Indexer<int,std::allocator<int>,VI> I4(cv);

Indexer<QI> I10(q);

this is what i wanted, and hence the problem is solved.
Thanks a lot to all.
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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top