469,622 Members | 1,462 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,622 developers. It's quick & easy.

template specialization for pointer-to-type

guess you have the following:

_________________________________________________
template <class T>
class CQVector
{
public:
// find an element, returns index or -1 if none is found
int find(int id) const;
private:
std::vector<Tm_vec;
};

template <class T>
int CQVector<T>::find(int id) const
{
int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt].ID() == id)
break;
}
return iCnt;
}
_________________________________________________

this finds an element in the vector by calling elements fn ID() and
compiles for all structures/classes that have an ID() memeber-fn
returning something comparable to int.
now i also want the possibility to store pointers, eg

CQVector<MyClass*m_foo;

and need some specialisation that does a...
_________________________________________________

int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt]->ID() == id)
break;
}
return iCnt;
_________________________________________________

what syntax is need ed for the specialisation?
something like template<class*Tdoesnt work...

TIA, -.rhavin;)
Jun 30 '08 #1
3 2153
On 7月1日, 上午2时59分, ".rhavin grobert" <cl...@yahoo.dewrote:
guess you have the following:

_________________________________________________
template <class T>
class CQVector
{
public:
// find an element, returns index or -1 if none is found
int find(int id) const;
private:
std::vector<Tm_vec;

};

template <class T>
int CQVector<T>::find(int id) const
{
int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt].ID() == id)
break;
}
return iCnt;}

_________________________________________________

this finds an element in the vector by calling elements fn ID() and
compiles for all structures/classes that have an ID() memeber-fn
returning something comparable to int.

now i also want the possibility to store pointers, eg

CQVector<MyClass*m_foo;

and need some specialisation that does a...
_________________________________________________

int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt]->ID() == id)
break;
}
return iCnt;
_________________________________________________

what syntax is need ed for the specialisation?
something like template<class*Tdoesnt work...

template <class T>
class CQVector<T*>
{
...
};
Jul 1 '08 #2

".rhavin grobert" <cl***@yahoo.dea 閏rit dans le message de news:
e2**********************************...oglegroups.com...
guess you have the following:

_________________________________________________
template <class T>
class CQVector
{
public:
// find an element, returns index or -1 if none is found
int find(int id) const;
private:
std::vector<Tm_vec;
};

template <class T>
int CQVector<T>::find(int id) const
{
int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt].ID() == id)
break;
}
return iCnt;
}
_________________________________________________

this finds an element in the vector by calling elements fn ID() and
compiles for all structures/classes that have an ID() memeber-fn
returning something comparable to int.
now i also want the possibility to store pointers, eg

CQVector<MyClass*m_foo;

and need some specialisation that does a...
_________________________________________________

int iCnt = m_vec.size();
while (iCnt-->0)
{
if (m_vec[iCnt]->ID() == id)
break;
}
return iCnt;
_________________________________________________

what syntax is need ed for the specialisation?
something like template<class*Tdoesnt work...

TIA, -.rhavin;)

No need to partially specialize your class by the way. Here an example.
#include <boost/utility.hpp>
#include <boost/type_traits.hpp>

using namespace std;

//This template function will be called only if T is a pointer. return type
is int
template<typename T>
typename boost::enable_if_c<boost::is_pointer<T>::value, int>::type
Do() {return 1;}

//This template function will be called only if T is NOT a pointer. return
type is int
template<typename T>
typename boost::disable_if_c<boost::is_pointer<T>::value, int>::type
Do() {return 2;}

template<typename T>
class A
{
public:
int DoSomething()
{
return Do<T>(); // Do actually take careof doing the right thing
depending on T
}
};

int main()
{
A<inta1;
A<int*a2;
cout <<a1.DoSomething() <<endl; // print 2
cout <<a2.DoSomething() <<endl; // print 1
return 0;
}

Ok I agree that the Do<Tfunction template could look a little (ok maybe
not just a little...) strange at first sight but it is not actually that
bad.

take for example

boost::enable_if_c<boost::is_pointer<T>::value, int>::type

there is 2 template arg to enable_if_c
1.boost::is_pointer<T>::value
2. int


Jul 1 '08 #3
>
No need to partially specialize your class by the way. Here an example.
#include <boost/utility.hpp>
#include <boost/type_traits.hpp>

using namespace std;

//This template function will be called only if T is a pointer. return
type is int
template<typename T>
typename boost::enable_if_c<boost::is_pointer<T>::value, int>::type
Do() {return 1;}

//This template function will be called only if T is NOT a pointer.
return type is int
template<typename T>
typename boost::disable_if_c<boost::is_pointer<T>::value, int>::type
Do() {return 2;}

template<typename T>
class A
{
public:
int DoSomething()
{
return Do<T>(); // Do actually take careof doing the right thing
depending on T
}
};

int main()
{
A<inta1;
A<int*a2;
cout <<a1.DoSomething() <<endl; // print 2
cout <<a2.DoSomething() <<endl; // print 1
return 0;
}

Ok I agree that the Do<Tfunction template could look a little (ok maybe
not just a little...) strange at first sight but it is not actually that
bad.

take for example

boost::enable_if_c<boost::is_pointer<T>::value, int>::type

there is 2 template arg to enable_if_c
1.boost::is_pointer<T>::value
2. int

Sorry, I pushed the wrong button...

ok so boost::is_pointer<T>::value will evaluate to true if T is a pointer
and false otherwise.
Inside enable_if_c, there is a simple typedef:
typedef T type;
it happen thet the second argument of the enable_if_c template is T (in our
case int)
so enable_if_c<true,int>::type == int and enable_if_c<true,MyClass>::type
== MyClass, and so on

So we can use the enable_if_c template as the return argument four our Do
function template.

Now what haapen when boost::is_pointer<T>::value evaluate to false? It is a
substitution failure (see the SFINAE principle). In short the compiler will
just reject the template and search for a better match (ok, if he does not
find a better match he will give you an error). In our case, the second Do
function will match for every non pointer type.

In your case, you seem to have only 1 function to "specialize"and it it is a
really simple function, so if you can install boost (www.boost.org) you
should consider this option.

----------------------
Eric Pruneau
Jul 1 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Agent Mulder | last post: by
reply views Thread by Patrick Kowalzick | last post: by
1 post views Thread by Rafal Dabrowa | last post: by
14 posts views Thread by SoilMan | last post: by
1 post views Thread by Bari | last post: by
7 posts views Thread by mathieu | last post: by
7 posts views Thread by (2b|!2b)==? | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.