By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,652 Members | 1,756 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,652 IT Pros & Developers. It's quick & easy.

matching multiple template

P: n/a
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
Jul 8 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a

"abir" <ab*******@gmail.coma écrit dans le message de news:
38**********************************...oglegroups.com...
>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
Jul 9 '08 #2

P: n/a
On Jul 9, 6:37 am, "Eric Pruneau" <eric.prun...@cgocable.cawrote:
"abir" <abirba...@gmail.coma écrit dans le message de news:
385bd2d8-d853-4e2d-bdad-35005952b...@p25g2000hsf.googlegroups.com...
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?
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>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
Jul 9 '08 #3

P: n/a
abir wrote:
[..]
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
Jul 9 '08 #4

P: n/a
[...]
>------------------------

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
Jul 10 '08 #5

P: n/a
On Jul 10, 7:25 am, "Eric Pruneau" <eric.prun...@cgocable.cawrote:
[...]
------------------------
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 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.
Jul 10 '08 #6

P: n/a
On Jul 10, 7:25 am, "Eric Pruneau" <eric.prun...@cgocable.cawrote:
[...]
------------------------
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<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
{
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
Jul 10 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.