Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > matching multiple template

Reply
Thread Tools

matching multiple template

 
 
abir
Guest
Posts: n/a
 
      07-08-2008
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
 
Reply With Quote
 
 
 
 
Eric Pruneau
Guest
Posts: n/a
 
      07-09-2008

"abir" <(E-Mail Removed)> a écrit dans le message de news:
385bd2d8-d853-4e2d-bdad-35005952bcba...oglegroups.com...
>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;
}

------------------------

Eric Pruneau


 
Reply With Quote
 
 
 
 
abir
Guest
Posts: n/a
 
      07-09-2008
On Jul 9, 6:37 am, "Eric Pruneau" <(E-Mail Removed)> wrote:
> "abir" <(E-Mail Removed)> a écrit dans le message de news:
> (E-Mail Removed)...
>
> >i have atemplate
> >template<typename S> class Indexer{};
> > i want to have a specialization for std::vector bothconst&nonconst
> > 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 isconstor nonconst?

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

>
> > 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 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;
>
> }
>
> ------------------------
>
> 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 a
proxy class to delegate the responsibility.

thanks
abir
 
Reply With Quote
 
Eric Pruneau
Guest
Posts: n/a
 
      07-10-2008
[...]

>> ------------------------
>>
>> 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<CONT>::type , const vector<T> >::value>::type
>

{
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!

-------------------------

Eric Pruneau


 
Reply With Quote
 
abir
Guest
Posts: n/a
 
      07-10-2008
On Jul 10, 7:25 am, "Eric Pruneau" <(E-Mail Removed)> wrote:
> [...]
>
>
>
> >> ------------------------

>
> >> 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<CONT>::type , const vector<T> >::value>::type
> >

> {
> 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!
>
> -------------------------
>
> Eric Pruneau


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....1ca1a6f5ae69b5
where i explained my intension also.
 
Reply With Quote
 
abir
Guest
Posts: n/a
 
      07-10-2008
On Jul 10, 7:25 am, "Eric Pruneau" <(E-Mail Removed)> wrote:
> [...]
>
>
>
> >> ------------------------

>
> >> 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<CONT>::type , const vector<T> >::value>::type
> >

> {
> 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!
>
> -------------------------
>
> Eric Pruneau


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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
template template arguments: expected a class template, got `Component<T1, T2, T3> gary.bernstein@gmail.com C++ 1 06-08-2007 07:10 AM
Help with Pattern matching. Matching multiple lines from while reading from a file. Bobby Chamness Perl Misc 2 05-03-2007 06:02 PM
Pattern matching : not matching problem Marc Bissonnette Perl Misc 9 01-13-2004 05:52 PM
Re: A Newbie Question about template template template tom_usenet C++ 0 07-24-2003 12:06 PM
Re: A Newbie Question about template template template Chris Theis C++ 2 07-24-2003 09:42 AM



Advertisments