Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   template specialization for pointer-to-type (http://www.velocityreviews.com/forums/t623098-template-specialization-for-pointer-to-type.html)

.rhavin grobert 06-30-2008 06:59 PM

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<T> m_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*T> doesnt work...

TIA, -.rhavin;)

Barry 07-01-2008 02:30 AM

Re: template specialization for pointer-to-type
 
On 7月1日, 上午2时59分, ".rhavin grobert" <cl...@yahoo.de> wrote:
> 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<T> m_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*T> doesnt work...
>



template <class T>
class CQVector<T*>
{
...
};

Eric Pruneau 07-01-2008 03:20 AM

Re: template specialization for pointer-to-type
 

".rhavin grobert" <clqrq@yahoo.de> a 閏rit dans le message de news:
e272f287-de27-4d6f-bff1-d1f0813b69d0...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<T> m_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*T> doesnt 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<int> a1;
A<int*> a2;
cout <<a1.DoSomething() <<endl; // print 2
cout <<a2.DoSomething() <<endl; // print 1
return 0;
}

Ok I agree that the Do<T> function 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









Eric Pruneau 07-01-2008 03:34 AM

Re: template specialization for pointer-to-type
 
>
> 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<int> a1;
> A<int*> a2;
> cout <<a1.DoSomething() <<endl; // print 2
> cout <<a2.DoSomething() <<endl; // print 1
> return 0;
> }
>
> Ok I agree that the Do<T> function 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




All times are GMT. The time now is 12:48 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.