template error with iterator

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

    template error with iterator

    Dear all,

    I was experimenting with a template taking two iterators for the range
    of
    a vector.(Perhaps , it is sth simple and I am missing it because it is
    a
    late hour.) I ran into problems in the compile phase , the code is
    below:

    #include <iostream>
    #include <algorithm>
    #include <stdexcept>
    #include <vector>

    using std::domain_err or;
    using std::sort;
    using std::vector;

    template <class T, class Ran>
    T median(Ran b, Ran e)
    {
    typedef typename vector<T>::size _type vec_sz;

    vec_sz size = (e-b)/sizeof(T);
    if (size == 0)
    throw domain_error("m edian of an empty vector");

    sort(b, e);

    vec_sz mid = size/2;

    return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
    }

    int main()
    {
    vector<doubleve c;
    for(int i=0;i!=10;++i)
    vec.push_back(i );
    std::cout << median(vec.begi n(), vec.end()) << std::endl;
    return 0;
    }


    I get

    83.cc: In function 'int main()':
    83.cc:38: error: no matching function for call to
    'median(__gnu_c xx::__normal_it erator<double*, std::vector<dou ble,
    std::allocator< double >, __gnu_cxx::__no rmal_iterator<d ouble*,
    std::vector<dou ble, std::allocator< double >)'

    I am supplying the median function with iterators by using the begin
    and
    end member functions of the vector. However, I get a type mismatch
    error
    on iterators I guess. Could you clarify the problem for me?

    Rgds,

    --
    Umut
  • utab

    #2
    Re: template error with iterator

    On May 13, 1:37 am, utab <umut.ta...@gma il.comwrote:
    Dear all,
    >
    I was experimenting with a template taking two iterators for the range
    of
    a vector.(Perhaps , it is sth simple and I am missing it because it is
    a
    late hour.) I ran into problems in the compile phase , the code is
    below:
    >
    #include <iostream>
    #include <algorithm>
    #include <stdexcept>
    #include <vector>
    >
    using std::domain_err or;
    using std::sort;
    using std::vector;
    >
    template <class T, class Ran>
    T median(Ran b, Ran e)
    {
    typedef typename vector<T>::size _type vec_sz;
    >
    vec_sz size = (e-b)/sizeof(T);
    if (size == 0)
    throw domain_error("m edian of an empty vector");
    >
    sort(b, e);
    >
    vec_sz mid = size/2;
    >
    return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
    >
    }
    >
    int main()
    {
    vector<doubleve c;
    for(int i=0;i!=10;++i)
    vec.push_back(i );
    std::cout << median(vec.begi n(), vec.end()) << std::endl;
    return 0;
    >
    }
    >
    I get
    >
    83.cc: In function 'int main()':
    83.cc:38: error: no matching function for call to
    'median(__gnu_c xx::__normal_it erator<double*, std::vector<dou ble,
    std::allocator< double >, __gnu_cxx::__no rmal_iterator<d ouble*,
    std::vector<dou ble, std::allocator< double >)'
    >
    I am supplying the median function with iterators by using the begin
    and
    end member functions of the vector. However, I get a type mismatch
    error
    on iterators I guess. Could you clarify the problem for me?
    >
    Rgds,
    >
    --
    Umut
    Forgot to tell that I use g++ 4.1.2

    Comment

    • tragomaskhalos

      #3
      Re: template error with iterator

      On 13 May, 00:37, utab <umut.ta...@gma il.comwrote:
      >
      template <class T, class Ran>
      T median(Ran b, Ran e)
      {
        typedef typename vector<T>::size _type vec_sz;
      >
        vec_sz size = (e-b)/sizeof(T);
        if (size == 0)
          throw domain_error("m edian of an empty vector");
      >
        sort(b, e);
      >
        vec_sz mid = size/2;
      >
        return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
      >
      }
      >
      int main()
      {
        vector<doubleve c;
        for(int i=0;i!=10;++i)
          vec.push_back(i );
        std::cout << median(vec.begi n(), vec.end()) << std::endl;
      The compiler cannot deduce T; replace the above call with
      median<double>( vec.begin(), vec.end())
      ^^^^^^
        return 0;
      >
      }
      >

      Comment

      • utab

        #4
        Re: template error with iterator

        On May 13, 1:47 am, tragomaskhalos <dave.du.verg.. .@logicacmg.com >
        wrote:
        On 13 May, 00:37, utab <umut.ta...@gma il.comwrote:
        >
        >
        >
        >
        >
        template <class T, class Ran>
        T median(Ran b, Ran e)
        {
        typedef typename vector<T>::size _type vec_sz;
        >
        vec_sz size = (e-b)/sizeof(T);
        if (size == 0)
        throw domain_error("m edian of an empty vector");
        >
        sort(b, e);
        >
        vec_sz mid = size/2;
        >
        return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
        >
        }
        >
        int main()
        {
        vector<doubleve c;
        for(int i=0;i!=10;++i)
        vec.push_back(i );
        std::cout << median(vec.begi n(), vec.end()) << std::endl;
        >
        The compiler cannot deduce T; replace the above call with
        median<double>( vec.begin(), vec.end())
        ^^^^^^
        >
        return 0;
        >
        }
        Thanks, I read something similar in the faq as well.

        Comment

        • acehreli@gmail.com

          #5
          Re: template error with iterator

          On May 12, 4:37 pm, utab <umut.ta...@gma il.comwrote:
          template <class T, class Ran>
          T median(Ran b, Ran e)
          {
          According to that definition, there is no relation between T and Ran.

          [...]
          std::cout << median(vec.begi n(), vec.end()) << std::endl;
          The complier cannot deduce T for that call because the return values
          are never a part of function signatures. You can try specifying it
          yourself:

          median<double>( vec.begin(), vec.end());

          Ali

          Comment

          • Paavo Helde

            #6
            Re: template error with iterator

            utab <umut.tabak@gma il.comwrote in news:50129083-18fd-4099-9ba7-
            586bb9df72e2@a2 3g2000hsc.googl egroups.com:
            Dear all,
            >
            I was experimenting with a template taking two iterators for the range
            of
            a vector.(Perhaps , it is sth simple and I am missing it because it is
            a
            late hour.) I ran into problems in the compile phase , the code is
            below:
            >
            #include <iostream>
            #include <algorithm>
            #include <stdexcept>
            #include <vector>
            >
            using std::domain_err or;
            using std::sort;
            using std::vector;
            >
            template <class T, class Ran>
            T median(Ran b, Ran e)
            {
            You are passing in only Ran arguments, there is no way the compiler could
            deduce the T template parameter.
            typedef typename vector<T>::size _type vec_sz;
            >
            vec_sz size = (e-b)/sizeof(T);
            if (size == 0)
            throw domain_error("m edian of an empty vector");
            >
            sort(b, e);
            >
            vec_sz mid = size/2;
            >
            return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
            }
            >
            int main()
            {
            vector<doubleve c;
            for(int i=0;i!=10;++i)
            vec.push_back(i );
            std::cout << median(vec.begi n(), vec.end()) << std::endl;
            ... so you have to specify it yourself:

            std::cout << median<double>( vec.begin(), vec.end()) << std::endl;

            ... or throw away the redundant template parameter:

            template <class Ran>
            typename Ran::value_type median(Ran b, Ran e)
            {
            typedef typename vector<Ran::val ue_type>::size_ type vec_sz;

            vec_sz size = (e-b)/sizeof(Ran::val ue_type);
            if (size == 0)
            throw domain_error("m edian of an empty vector");

            ....

            hth
            Paavo

            Comment

            • Greg Herlihy

              #7
              Re: template error with iterator

              On May 12, 4:37 pm, utab <umut.ta...@gma il.comwrote:
              I was experimenting with a template taking two iterators for the range
              of
              a vector.(Perhaps , it is sth simple and I am missing it because it is
              a
              late hour.) I ran into problems in the compile phase , the code is
              below:
              >
              #include <iostream>
              #include <algorithm>
              #include <stdexcept>
              #include <vector>
              >
              using std::domain_err or;
              using std::sort;
              using std::vector;
              >
              template <class T, class Ran>
              T median(Ran b, Ran e)
              {
                typedef typename vector<T>::size _type vec_sz;
              >
                vec_sz size = (e-b)/sizeof(T);
                if (size == 0)
                  throw domain_error("m edian of an empty vector");
              >
                sort(b, e);
              >
                vec_sz mid = size/2;
              >
                return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
              }
              The C++ compiler is not able to deduce the type "T" from the median()
              function call. Since "T" is dependent on the iterator type "Ran", I
              would eliminate "T" altogether. Note also that the calculation of
              "size" is incorrect - e-b will return the number of positions between
              two random access iterators.

              Applying these suggestions produces a program like this one:

              #include <iostream>
              #include <algorithm>
              #include <stdexcept>
              #include <vector>
              #include <iterator>

              using std::domain_err or;
              using std::sort;
              using std::vector;

              template <class Ran>
              typename std::iterator_t raits<Ran>::val ue_type
              median(Ran b, Ran e)
              {
              size_t size = e-b;
              if (size == 0)
              throw domain_error("m edian of an empty vector");
              sort(b, e);
              size_t mid = size/2;
              return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
              }

              int main()
              {
              vector<doubleve c;

              for (int i=0; i!=10; ++i)
              vec.push_back(i );

              std::cout << median(vec.begi n(), vec.end()) << std::endl;
              return 0;
              }

              Greg

              Comment

              • James Kanze

                #8
                Re: template error with iterator

                On May 13, 1:57 am, Paavo Helde <nob...@ebi.eew rote:
                utab <umut.ta...@gma il.comwrote in news:50129083-18fd-4099-9ba7-
                586bb9df7...@a2 3g2000hsc.googl egroups.com:
                I was experimenting with a template taking two iterators for
                the range of a vector.(Perhaps , it is sth simple and I am
                missing it because it is a late hour.) I ran into problems
                in the compile phase , the code is below:
                [...]
                .. or throw away the redundant template parameter:
                template <class Ran>
                typename Ran::value_type median(Ran b, Ran e)
                There's no guarantee that Ran has a typedef for value_type (and
                there have definitely been implementations of the standard
                library where it didn't for std::vector<>).

                This should be:

                template< typename RandomAccessIte rator >
                typename std::iterator_t raits< RandomAccessIte rator >::value_type
                median( RandomAccessIte rator begin, RandomAccessIte rator end )
                {
                typedef typename vector<Ran::val ue_type>::size_ type vec_sz;
                And here, even worse, since you're tying yourself to
                std::vector. (Even as it stands, you need an additional
                typename in the template argument.) Also, the difference
                between to random access iterators is a difference_type , not a
                size_type. So it should be:

                typedef typename std::iterator_t raits< RandomAccessIte rator >
                ::difference_ty pe SequenceSize ;
                vec_sz size = (e-b)/sizeof(Ran::val ue_type);
                And of course, you don't want the division.

                --
                James Kanze (GABI Software) email:james.kan ze@gmail.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                Working...