Connecting Tech Pros Worldwide Help | Site Map
 
 
LinkBack Thread Tools Search this Thread
  #1  
Old July 8th, 2008, 07:25 AM
abir
Guest
 
Posts: n/a
Default matching multiple template

i have a template
template<typename Sclass Indexer{};
i want to have a specialization for std::vector both const & non const
version.
template<typename T,typename Aclass 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,Aconst & non
const other for std::deque<T,Aconst & non const.

thanks
abir
  #2  
Old July 9th, 2008, 02:45 AM
Eric Pruneau
Guest
 
Posts: n/a
Default Re: matching multiple template


"abir" <abirbasak@gmail.coma écrit dans le message de news:
385bd2d8-d853-4e2d-bdad-35005952bcba...oglegroups.com...
Quote:
>i have a template
template<typename Sclass Indexer{};
i want to have a specialization for std::vector both const & non const
version.
template<typename T,typename Aclass 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,Aconst & non
const other for std::deque<T,Aconst & 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<intconst c; // print 3
Indexer<int, deque<intconst d; // print 5

return 0;
}

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

Eric Pruneau


  #3  
Old July 9th, 2008, 03:05 PM
abir
Guest
 
Posts: n/a
Default Re: matching multiple template

On Jul 9, 6:37 am, "Eric Pruneau" <eric.prun...@cgocable.cawrote:
Quote:
"abir" <abirba...@gmail.coma écrit dans le message de news:
385bd2d8-d853-4e2d-bdad-35005952b...@p25g2000hsf.googlegroups.com...
>
Quote:
i have atemplate
template<typename Sclass Indexer{};
i want to have a specialization for std::vector bothconst&nonconst
version.
template<typename T,typename Aclass Indexer<std::vector<T,A {}
matches only with nonconst version. anyway to match it for both? and
get if it isconstor nonconst?
>
Quote:
Actually i want 2 specialization, one for std::vector<T,A>const&non
constother for std::deque<T,A>const&nonconst.
>
Quote:
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>constc; // print 3
Indexer<int, deque<int>constd; // 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
  #4  
Old July 9th, 2008, 03:05 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: matching multiple template

abir wrote:
Quote:
[..]
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.
Did you see my reply to Salt_Peter in the other thread? Please take
a look at it and tell me what isn't satisfactory. The top-level 'const'
does not seem to have an impact at all in my code, but it might in yours
so you need to explain better what is different between my code and what
you need.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
  #5  
Old July 10th, 2008, 03:35 AM
Eric Pruneau
Guest
 
Posts: n/a
Default Re: matching multiple template

[...]
Quote:
Quote:
>------------------------
>>
>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
Quote:
>
{
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


  #6  
Old July 10th, 2008, 06:45 AM
abir
Guest
 
Posts: n/a
Default Re: matching multiple template

On Jul 10, 7:25 am, "Eric Pruneau" <eric.prun...@cgocable.cawrote:
Quote:
[...]
>
>
>
Quote:
Quote:
------------------------
>
Quote:
Quote:
Eric Pruneau
>
Quote:
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"; }
>
Quote:
};
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.
>
Quote:
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
Quote:
>
{
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 Aclass 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.
  #7  
Old July 10th, 2008, 07:25 AM
abir
Guest
 
Posts: n/a
Default Re: matching multiple template

On Jul 10, 7:25 am, "Eric Pruneau" <eric.prun...@cgocable.cawrote:
Quote:
[...]
>
>
>
Quote:
Quote:
------------------------
>
Quote:
Quote:
Eric Pruneau
>
Quote:
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"; }
>
Quote:
};
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.
>
Quote:
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
Quote:
>
{
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
Quote:
{
public:
typedef Indexer<Sself_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
Quote:
{
public:
typedef Indexer<Sself_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<intVI;
VI v;
Indexer<VII1(v);
Indexer<const VII2(v);
Indexer<const VII3(cv);
//Indexer<int,std::allocator<int>,VII4(cv);

Indexer<QII10(q);

this is what i wanted, and hence the problem is solved.
Thanks a lot to all.
abir
 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 205,338 network members.