matching multiple template

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

    matching multiple template

    i have a template
    template<typena me Sclass Indexer{};
    i want to have a specialization for std::vector both const & non const
    version.
    template<typena me T,typename Aclass Indexer<std::ve ctor<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,A const & non
    const other for std::deque<T,Ac onst & non const.

    thanks
    abir
  • Eric Pruneau

    #2
    Re: matching multiple template


    "abir" <abirbasak@gmai l.coma écrit dans le message de news:
    385bd2d8-d853-4e2d-bdad-35005952bcba...l egroups.com...
    >i have a template
    template<typena me Sclass Indexer{};
    i want to have a specialization for std::vector both const & non const
    version.
    template<typena me T,typename Aclass Indexer<std::ve ctor<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,A const & non
    const other for std::deque<T,Ac onst & 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<typena me 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<typena me T, typename CONT>
    struct Indexer
    {
    Indexer() { cout <<"1\n"; }
    };

    template<typena me T>
    struct Indexer<T, vector<T
    {
    Indexer() { cout <<"2\n"; }
    };

    template<typena me T>
    struct Indexer<T, const vector<T
    {
    Indexer() { cout <<"3\n"; }
    };

    template<typena me T>
    struct Indexer<T, deque<T
    {
    Indexer() { cout <<"4\n"; }
    };

    template<typena me 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


    Comment

    • abir

      #3
      Re: matching multiple template

      On Jul 9, 6:37 am, "Eric Pruneau" <eric.prun...@c gocable.cawrote :
      "abir" <abirba...@gmai l.coma écrit dans le message de news:
      385bd2d8-d853-4e2d-bdad-35005952b...@p2 5g2000hsf.googl egroups.com...
      >
      i have atemplate
      template<typena me Sclass Indexer{};
      i want to have a specialization for std::vector bothconst&nonco nst
      version.
      template<typena me T,typename Aclass Indexer<std::ve ctor<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<typena me 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 allocatortempla te
      parameter to simplify the example but I amsure you will find a way to
      integrate it!!!
      >
      template<typena me T, typename CONT>
      struct Indexer
      {
      Indexer() { cout <<"1\n"; }
      >
      };
      >
      template<typena me T>
      struct Indexer<T, vector<T
      {
      Indexer() { cout <<"2\n"; }
      >
      };
      >
      template<typena me T>
      struct Indexer<T,const vector<T
      {
      Indexer() { cout <<"3\n"; }
      >
      };
      >
      template<typena me T>
      struct Indexer<T, deque<T
      {
      Indexer() { cout <<"4\n"; }
      >
      };
      >
      template<typena me 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<int>cons tc; // print 3
      Indexer<int, deque<int>const d; // 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<typena me 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

      Comment

      • Victor Bazarov

        #4
        Re: matching multiple template

        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<typena me 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

        Comment

        • Eric Pruneau

          #5
          Re: matching multiple template

          [...]
          >------------------------
          >>
          >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<typen ame 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<typena me T, typename CONT, typename enable=void>
          struct Indexer
          {
          Indexer() { cout <<"1\n"; }
          };

          // this one could be a bit scary....

          template<typena me T, typename CONT>
          struct Indexer<T, CONT, typename boost::enable_i f_c<boost::is_s ame<
          typename boost::add_cons t<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<tru e>::type return void
          enable_if_c<fal se>::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


          Comment

          • abir

            #6
            Re: matching multiple template

            On Jul 10, 7:25 am, "Eric Pruneau" <eric.prun...@c gocable.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<typena me 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<typena me T, typename CONT, typename enable=void>
            struct Indexer
            {
            Indexer() { cout <<"1\n"; }
            >
            };
            >
            // this one could be a bit scary....
            >
            template<typena me T, typename CONT>
            struct Indexer<T, CONT, typename boost::enable_i f_c<boost::is_s ame<
            typename boost::add_cons t<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<tru e>::type return void
            enable_if_c<fal se>::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<i nt 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

            where i explained my intension also.

            Comment

            • abir

              #7
              Re: matching multiple template

              On Jul 10, 7:25 am, "Eric Pruneau" <eric.prun...@c gocable.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<typena me 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<typena me T, typename CONT, typename enable=void>
              struct Indexer
              {
              Indexer() { cout <<"1\n"; }
              >
              };
              >
              // this one could be a bit scary....
              >
              template<typena me T, typename CONT>
              struct Indexer<T, CONT, typename boost::enable_i f_c<boost::is_s ame<
              typename boost::add_cons t<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<tru e>::type return void
              enable_if_c<fal se>::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_typ e is T,
              so my final version is

              template<typena me S,typename enable = void>
              class Indexer;

              template<typena me S>
              class Indexer<S,typen ame boost::enable_i f_c<std::tr1::i s_same<
              typename std::tr1::add_c onst<S>::type, const
              std::vector<typ ename S::value_type,t ypename
              S::allocator_ty pe>>::value>::t ype
              {
              public:
              typedef Indexer<Sself_t ype;
              typedef Indexer<typenam e std::tr1::remov e_const<S>::typ e>
              nonconst_self;
              public:
              Indexer(S& s) {
              std::cout<<"vec ctor\n";
              }
              Indexer(noncons t_self& s){
              std::cout<<"vec copy\n";
              }
              };
              template<typena me S>
              class Indexer<S,typen ame boost::enable_i f_c<std::tr1::i s_same<
              typename boost::add_cons t<S>::type, const
              std::deque<type name S::value_type,t ypename
              S::allocator_ty pe>>::value>::t ype
              {
              public:
              typedef Indexer<Sself_t ype;
              typedef Indexer<typenam e std::tr1::remov e_const<S>::typ e>
              nonconst_self;
              public:
              Indexer(S& s) {
              std::cout<<"deq ctor\n";
              }
              Indexer(noncons t_self& s){
              std::cout<<"deq copy\n";
              }
              };

              and calling syntax is
              typedef std::vector<int VI;
              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

              Comment

              Working...