template specialization for pointer-to-type

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • .rhavin grobert

    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>::fi nd(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<MyClas s*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;)
  • Barry

    #2
    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<Tm_ vec;
    >
    };
    >
    template <class T>
    int CQVector<T>::fi nd(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<MyClas s*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*>
    {
    ...
    };

    Comment

    • Eric Pruneau

      #3
      Re: template specialization for pointer-to-type


      ".rhavin grobert" <clqrq@yahoo.de a écrit dans le message de news:
      e272f287-de27-4d6f-bff1-d1f0813b69d0...l egroups.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>::fi nd(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<MyClas s*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<typena me T>
      typename boost::enable_i f_c<boost::is_p ointer<T>::valu e, int>::type
      Do() {return 1;}

      //This template function will be called only if T is NOT a pointer. return
      type is int
      template<typena me T>
      typename boost::disable_ if_c<boost::is_ pointer<T>::val ue, int>::type
      Do() {return 2;}

      template<typena me 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.DoSomethin g() <<endl; // print 2
      cout <<a2.DoSomethin g() <<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_i f_c<boost::is_p ointer<T>::valu e, int>::type

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








      Comment

      • Eric Pruneau

        #4
        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<typena me T>
        typename boost::enable_i f_c<boost::is_p ointer<T>::valu e, int>::type
        Do() {return 1;}
        >
        //This template function will be called only if T is NOT a pointer.
        return type is int
        template<typena me T>
        typename boost::disable_ if_c<boost::is_ pointer<T>::val ue, int>::type
        Do() {return 2;}
        >
        template<typena me 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.DoSomethin g() <<endl; // print 2
        cout <<a2.DoSomethin g() <<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_i f_c<boost::is_p ointer<T>::valu e, int>::type
        >
        there is 2 template arg to enable_if_c
        1.boost::is_poi nter<T>::value
        2. int

        Sorry, I pushed the wrong button...

        ok so boost::is_point er<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<tru e,int>::type == int and enable_if_c<tru e,MyClass>::typ e
        == 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_point er<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


        Comment

        Working...