![]() |
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;) |
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*> { ... }; |
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 |
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 10:08 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.