Convert from std::vector<double> to std::vector<int>

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

    Convert from std::vector<double> to std::vector<int>

    Is there a non-brute force method of doing this?
    transform() looked likely but had no predefined function object.


    std::vector<dou ble> src;
    std::vector<int > dest;

    std::vector<dou ble>::size_type size = src.size();
    dest.reserve(si ze);
    for (std::vector<in t>::size_type i = 0;
    i < size;
    i++)
    {
    dest[i] = static_cast<int >(src[i]);
    }
  • Andrew Koenig

    #2
    Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

    "Anonymous" <inetladd@hotma il.com> wrote in message
    news:inetladd-B7EC3F.20001127 032005@news-fe-03.texas.rr.com ...
    [color=blue]
    > Is there a non-brute force method of doing this?
    > transform() looked likely but had no predefined function object.[/color]
    [color=blue]
    > std::vector<dou ble> src;
    > std::vector<int > dest;
    >
    > std::vector<dou ble>::size_type size = src.size();
    > dest.reserve(si ze);
    > for (std::vector<in t>::size_type i = 0;
    > i < size;
    > i++)
    > {
    > dest[i] = static_cast<int >(src[i]);
    > }[/color]

    How about this?

    std::vector<int > dest(src.begin( ), src.end());

    I can't recall any requirement that the iterators used to initialize a
    vector must refer to values of the same type as the vector elements.


    Comment

    • Malte Starostik

      #3
      Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

      Andrew Koenig schrieb:[color=blue]
      > "Anonymous" <inetladd@hotma il.com> wrote in message
      > news:inetladd-B7EC3F.20001127 032005@news-fe-03.texas.rr.com ...
      >
      >[color=green]
      >>Is there a non-brute force method of doing this?
      >>transform() looked likely but had no predefined function object.[/color]
      >
      >[color=green]
      >>std::vector<d ouble> src;
      >>std::vector<i nt> dest;
      >>
      >>std::vector<d ouble>::size_ty pe size = src.size();
      >>dest.reserve( size);
      >>for (std::vector<in t>::size_type i = 0;
      >> i < size;
      >> i++)
      >>{
      >> dest[i] = static_cast<int >(src[i]);
      >>}[/color]
      >
      >
      > How about this?
      >
      > std::vector<int > dest(src.begin( ), src.end());
      >
      > I can't recall any requirement that the iterators used to initialize a
      > vector must refer to values of the same type as the vector elements.[/color]

      Right, that's the straightforward way and it works, but can result in a
      rather longish warning about the double->int conversion:

      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_algobase.h:
      In
      function `_OutputIter std::__copy(_Ra ndomAccessIter, _RandomAccessIt er,
      _OutputIter, std::random_acc ess_iterator_ta g) [with _RandomAccessIt er =
      double*, _OutputIter = int*]':
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_algobase.h: 266:
      instantiated from `_OutputIter std::__copy_aux 2(_InputIter,
      _InputIter, _OutputIter, __true_type) [with _InputIter = double*,
      _OutputIter = int*]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_algobase.h: 303:
      instantiated from `_OutputIter std::__copy_ni2 (_InputIter, _InputIter,
      _OutputIter, __false_type) [with _InputIter = double*, _OutputIter = int*]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_algobase.h: 314:
      instantiated from `_OutputIter std::__copy_ni1 (_InputIter, _InputIter,
      _OutputIter, __true_type) [with _InputIter =
      __gnu_cxx::__no rmal_iterator<d ouble*, std::vector<dou ble,
      std::allocator< double> > >, _OutputIter = int*]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_algobase.h: 349:
      instantiated from `_OutputIter std::copy(_Inpu tIter, _InputIter,
      _OutputIter) [with _InputIter = __gnu_cxx::__no rmal_iterator<d ouble*,
      std::vector<dou ble, std::allocator< double> > >, _OutputIter = int*]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_uninitializ ed.h:76:
      instantiated from `_ForwardIter
      std::__uninitia lized_copy_aux( _InputIter, _InputIter, _ForwardIter,
      __true_type) [with _InputIter = __gnu_cxx::__no rmal_iterator<d ouble*,
      std::vector<dou ble, std::allocator< double> > >, _ForwardIter = int*]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_uninitializ ed.h:112:
      instantiated from `_ForwardIter std::uninitiali zed_copy(_Input Iter,
      _InputIter, _ForwardIter) [with _InputIter =
      __gnu_cxx::__no rmal_iterator<d ouble*, std::vector<dou ble,
      std::allocator< double> > >, _ForwardIter = int*]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_vector.h:82 9:
      instantiated from `void std::vector<_Tp ,
      _Alloc>::_M_ran ge_initialize(_ ForwardIterator , _ForwardIterato r,
      std::forward_it erator_tag) [with _ForwardIterato r =
      __gnu_cxx::__no rmal_iterator<d ouble*, std::vector<dou ble,
      std::allocator< double> > >, _Tp = int, _Alloc = std::allocator< int>]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_vector.h:80 7:
      instantiated from `void std::vector<_Tp ,
      _Alloc>::_M_ini tialize_dispatc h(_InputIter, _InputIter, __false_type)
      [with _InputIter = __gnu_cxx::__no rmal_iterator<d ouble*,
      std::vector<dou ble, std::allocator< double> > >, _Tp = int, _Alloc =
      std::allocator< int>]'
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_vector.h:28 9:
      instantiated from `std::vector<_T p, _Alloc>::vector (_InputIterator ,
      _InputIterator, typename std::_Vector_ba se<_Tp,
      _Alloc>::alloca tor_type&) [with _InputIterator =
      __gnu_cxx::__no rmal_iterator<d ouble*, std::vector<dou ble,
      std::allocator< double> > >, _Tp = int, _Alloc = std::allocator< int>]'
      foo.cpp:6: instantiated from here
      /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_algobase.h: 241:
      warning: converting
      to `int' from `double'

      Cheers,
      Malte

      Comment

      • Donovan Rebbechi

        #4
        Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

        On 2005-03-28, Anonymous <inetladd@hotma il.com> wrote:[color=blue]
        > Is there a non-brute force method of doing this?
        > transform() looked likely but had no predefined function object.[/color]

        I'd just wrap static_cast in a function object, e.g.

        template <typename T>
        struct Static_cast {
        template <typename U>
        T operator () (const U& x) const { return static_cast<T> (x); }
        };

        Not pretty, but gets the job done and shuts the compiler up. I happen to
        believe that being able to explicitly "cast" one container to another is a
        good enough reason to write a 5 line function object.

        Cheers,
        --
        Donovan Rebbechi

        Comment

        • Malte Starostik

          #5
          Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

          Donovan Rebbechi schrieb:[color=blue]
          > On 2005-03-28, Anonymous <inetladd@hotma il.com> wrote:
          >[color=green]
          >>Is there a non-brute force method of doing this?
          >>transform() looked likely but had no predefined function object.[/color]
          >
          >
          > I'd just wrap static_cast in a function object, e.g.
          >
          > template <typename T>
          > struct Static_cast {
          > template <typename U>
          > T operator () (const U& x) const { return static_cast<T> (x); }
          > };
          >
          > Not pretty, but gets the job done and shuts the compiler up. I happen to
          > believe that being able to explicitly "cast" one container to another is a
          > good enough reason to write a 5 line function object.[/color]

          I totally agree. Minor nitpick though: no need to use static_cast to
          convert int to double. The functional notation is enough and IMHO
          conveys less of the feeling of doing something bad ;-)
          return T( x );
          Of course that limits a function object like the one above.

          Cheers,
          Malte

          Comment

          • Pete Becker

            #6
            Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

            Malte Starostik wrote:[color=blue]
            >
            > Right, that's the straightforward way and it works, but can result in a
            > rather longish warning about the double->int conversion:[/color]

            So turn of that G** D***** warning. Just because some compiler writer
            thinks you can't be trusted to convert doubles to ints doesn't mean you
            have to believe it.

            --

            Pete Becker
            Dinkumware, Ltd. (http://www.dinkumware.com)

            Comment

            • Pete Becker

              #7
              Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

              Donovan Rebbechi wrote:
              [color=blue]
              >
              > Not pretty, but gets the job done and shuts the compiler up. I happen to
              > believe that being able to explicitly "cast" one container to another is a
              > good enough reason to write a 5 line function object.
              >[/color]

              Even better is to use the built-in conversions as they were designed to
              be used. Writing a five line function object just to satisfy some
              compiler writer's notion of good form is a waste of time.

              --

              Pete Becker
              Dinkumware, Ltd. (http://www.dinkumware.com)

              Comment

              • Donovan Rebbechi

                #8
                Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

                On 2005-03-28, Pete Becker <petebecker@acm .org> wrote:[color=blue]
                > Donovan Rebbechi wrote:
                >[color=green]
                >>
                >> Not pretty, but gets the job done and shuts the compiler up. I happen to
                >> believe that being able to explicitly "cast" one container to another is a
                >> good enough reason to write a 5 line function object.
                >>[/color]
                >
                > Even better is to use the built-in conversions as they were designed to
                > be used. Writing a five line function object just to satisfy some
                > compiler writer's notion of good form is a waste of time.[/color]

                But chasing some error that the compiler warned you about is a potential
                timesink, because you turned down warning levels, or because the warnings
                were hidden among dozens of lines of noise is an even bigger waste of time.
                Writing a small wrapper around static_cast is a minor inconvenience at worst.
                Of course you understand this -- so how would you go about managing the
                problem of noisy warnings ?

                Suppose there is a "borderline " warning that is sometimes useful and sometimes
                just annoying. (I'd consider this to be such an example) Do you turn warning
                levels down, or do you turn them up, but then find some way to supress or
                filter the resulting noise ? Or is it your opinion that my premise is just
                plain wrong, and there is no such thing as a "borderling " warning ?

                Cheers,
                --
                Donovan Rebbechi

                Comment

                • Pete Becker

                  #9
                  Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

                  Donovan Rebbechi wrote:
                  [color=blue]
                  > On 2005-03-28, Pete Becker <petebecker@acm .org> wrote:
                  >[color=green]
                  >>Donovan Rebbechi wrote:
                  >>
                  >>[color=darkred]
                  >>>Not pretty, but gets the job done and shuts the compiler up. I happen to
                  >>>believe that being able to explicitly "cast" one container to another is a
                  >>>good enough reason to write a 5 line function object.
                  >>>[/color]
                  >>
                  >>Even better is to use the built-in conversions as they were designed to
                  >>be used. Writing a five line function object just to satisfy some
                  >>compiler writer's notion of good form is a waste of time.[/color]
                  >
                  >
                  > But chasing some error that the compiler warned you about is a potential
                  > timesink, because you turned down warning levels, or because the warnings
                  > were hidden among dozens of lines of noise is an even bigger waste of time.[/color]

                  And chasing some error that the compiler didn't warn you about because
                  someone added a cast to get rid of the warning is a potential timesink,
                  made worse by wrapping the cast in dozens <g> of lines of otherwise
                  extraneous code.
                  [color=blue]
                  > Writing a small wrapper around static_cast is a minor inconvenience at worst.\[/color]

                  Any time you're rewriting correct, meaningful code in order to silence a
                  warning you're wasting time. And, of course, you can't assume that
                  someone who added a cast had thought about what the code did; they might
                  have added it just to silence the warning. After all, that's the goal:
                  your code should compile without warnings. Doesn't matter if it's
                  correct, so long as it's quiet. <g>
                  [color=blue]
                  > Of course you understand this -- so how would you go about managing the
                  > problem of noisy warnings ?[/color]

                  Turn 'em off.
                  [color=blue]
                  >
                  > Suppose there is a "borderline " warning that is sometimes useful and sometimes
                  > just annoying. (I'd consider this to be such an example) Do you turn warning
                  > levels down, or do you turn them up, but then find some way to supress or
                  > filter the resulting noise ? Or is it your opinion that my premise is just
                  > plain wrong, and there is no such thing as a "borderling " warning ?
                  >[/color]

                  Too many programmers today treat the compiler as a surrogate brain, and
                  rely on warnings to remind them that they haven't thought about the
                  consequences of what they've done. If you're writing code that converts
                  a double to an int you'd better know what the limitations on that are,
                  and you'd better take the time to analyze where the double comes from
                  and assure yourself that the conversion will do what you need to do.
                  That's basic software engineering. Warnings don't change that. At best
                  they become a checklist of places where you haven't finished your work.
                  There are much more effective ways of doing that, beginning with not
                  leaving a piece of code until you understand it. That way you don't have
                  to remember to look at it again later.

                  Tom DeMarco, in a book called "Controllin g Software Projects,"
                  recommended (perhaps tongue in cheek) that programmers not be allowed to
                  use compilers; compiling their code would be part of the test phase, not
                  the development phase.

                  --

                  Pete Becker
                  Dinkumware, Ltd. (http://www.dinkumware.com)

                  Comment

                  • Yuriy Solodkyy

                    #10
                    Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

                    I was always wondering why compiler writers won't create a common
                    numeration or classification for at least common errors and warnings. In
                    this way developers would have been able to temporary disable and then
                    reenable a particular warning via #pragma (don't know how portable
                    pragmas are, but it's a nice way in some compilers to explicitly say to
                    compiler that you know what you are doing).

                    Yuriy

                    Donovan Rebbechi wrote:[color=blue]
                    > On 2005-03-28, Pete Becker <petebecker@acm .org> wrote:
                    >[color=green]
                    >>Donovan Rebbechi wrote:
                    >>
                    >>[color=darkred]
                    >>>Not pretty, but gets the job done and shuts the compiler up. I happen to
                    >>>believe that being able to explicitly "cast" one container to another is a
                    >>>good enough reason to write a 5 line function object.
                    >>>[/color]
                    >>
                    >>Even better is to use the built-in conversions as they were designed to
                    >>be used. Writing a five line function object just to satisfy some
                    >>compiler writer's notion of good form is a waste of time.[/color]
                    >
                    >
                    > But chasing some error that the compiler warned you about is a potential
                    > timesink, because you turned down warning levels, or because the warnings
                    > were hidden among dozens of lines of noise is an even bigger waste of time.
                    > Writing a small wrapper around static_cast is a minor inconvenience at worst.
                    > Of course you understand this -- so how would you go about managing the
                    > problem of noisy warnings ?
                    >
                    > Suppose there is a "borderline " warning that is sometimes useful and sometimes
                    > just annoying. (I'd consider this to be such an example) Do you turn warning
                    > levels down, or do you turn them up, but then find some way to supress or
                    > filter the resulting noise ? Or is it your opinion that my premise is just
                    > plain wrong, and there is no such thing as a "borderling " warning ?
                    >
                    > Cheers,[/color]

                    Comment

                    • Duane Hebert

                      #11
                      Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;


                      "Pete Becker" <petebecker@acm .org> wrote in message news:O7ednbMn84 s4hNXfRVn-jg@giganews.com ...[color=blue]
                      > Malte Starostik wrote:[color=green]
                      > >
                      > > Right, that's the straightforward way and it works, but can result in a
                      > > rather longish warning about the double->int conversion:[/color]
                      >
                      > So turn of that G** D***** warning. Just because some compiler writer
                      > thinks you can't be trusted to convert doubles to ints doesn't mean you
                      > have to believe it.[/color]

                      Or just use a static_cast.


                      Comment

                      • Pete Becker

                        #12
                        Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

                        Duane Hebert wrote:[color=blue]
                        > "Pete Becker" <petebecker@acm .org> wrote in message news:O7ednbMn84 s4hNXfRVn-jg@giganews.com ...
                        >[color=green]
                        >>Malte Starostik wrote:
                        >>[color=darkred]
                        >>>Right, that's the straightforward way and it works, but can result in a
                        >>>rather longish warning about the double->int conversion:[/color]
                        >>
                        >>So turn of that G** D***** warning. Just because some compiler writer
                        >>thinks you can't be trusted to convert doubles to ints doesn't mean you
                        >>have to believe it.[/color]
                        >
                        >
                        > Or just use a static_cast.
                        >
                        >[/color]

                        To "just use a static_cast" in this case requires writing a function
                        object to pass to an algorithm, instead of simply using the vector
                        constructor that takes a pair of iterators.

                        --

                        Pete Becker
                        Dinkumware, Ltd. (http://www.dinkumware.com)

                        Comment

                        • Howard

                          #13
                          Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;


                          "Pete Becker" <petebecker@acm .org> wrote in message
                          news:eZudnR5dqu tTodXfRVn-qA@giganews.com ...

                          [color=blue]
                          >
                          > Tom DeMarco, in a book called "Controllin g Software Projects," recommended
                          > (perhaps tongue in cheek) that programmers not be allowed to use
                          > compilers; compiling their code would be part of the test phase, not the
                          > development phase.
                          >[/color]

                          Ah, that takes me back to my early years in college: drawing flowcharts,
                          writing pseduo-code, filling out coding forms, entering the final code
                          verbatim from those forms, submitting it all to a batch system, and waiting
                          until the next day to find out I'd left out a period on the third line of my
                          COBOL app, resulting in seventeen pages of errors and an automatic reduction
                          of my best possible grade by 5%. I sure do miss those exciting, productive
                          times. Sigh...

                          :-)

                          -Howard




                          Comment

                          • Howard Hinnant

                            #14
                            Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

                            In article <toCdncZH8JXjzN XfRVn-uA@giganews.com >,
                            Pete Becker <petebecker@acm .org> wrote:
                            [color=blue]
                            > Duane Hebert wrote:[color=green]
                            > > "Pete Becker" <petebecker@acm .org> wrote in message
                            > > news:O7ednbMn84 s4hNXfRVn-jg@giganews.com ...
                            > >[color=darkred]
                            > >>Malte Starostik wrote:
                            > >>
                            > >>>Right, that's the straightforward way and it works, but can result in a
                            > >>>rather longish warning about the double->int conversion:
                            > >>
                            > >>So turn of that G** D***** warning. Just because some compiler writer
                            > >>thinks you can't be trusted to convert doubles to ints doesn't mean you
                            > >>have to believe it.[/color]
                            > >
                            > >
                            > > Or just use a static_cast.
                            > >
                            > >[/color]
                            >
                            > To "just use a static_cast" in this case requires writing a function
                            > object to pass to an algorithm, instead of simply using the vector
                            > constructor that takes a pair of iterators.[/color]

                            Or instead maybe write a templated "casting iterator" which would
                            certainly be more trouble up front, but more reusable down the road.

                            Maybe something like (untested and many details left out):

                            template <class To, class From>
                            class op_static_cast
                            {
                            ...
                            typedef typename iterator_traits <To>::value_typ e value_type;
                            value_type operator () (const From& f) const
                            {return static_cast<val ue_type>(*f);}
                            };

                            template <class Cast>
                            class cast_iterator
                            {
                            ...
                            value_type operator*() const {return c_(i_);}
                            ...
                            private:
                            from i_;
                            Cast c_;
                            };

                            vector<double> vd;
                            ....
                            typedef cast_iterator
                            <
                            op_static_cast
                            <
                            vector<int>::it erator,
                            vector<double>: :iterator[color=blue]
                            >
                            > It;[/color]
                            vector<int> vi(It(vd.begin( ), It(vd.end()));

                            This is unfortunately likely to bend (or break) some rules on the
                            iterator categories (like forward iterators must return references).
                            But it is also likely to work flawlessly (assuming your compiler can
                            inline everything).

                            All that being said, I sympathize with Pete's argument. But sometimes
                            the warning level for a piece of code is a political issue instead of a
                            technical issue.

                            -Howard

                            Comment

                            • Pete Becker

                              #15
                              Re: Convert from std::vector&lt; double&gt; to std::vector&lt; int&gt;

                              Howard Hinnant wrote:[color=blue]
                              >
                              > Or instead maybe write a templated "casting iterator" which would
                              > certainly be more trouble up front, but more reusable down the road.
                              >[/color]

                              Sure, there are all sorts of things people can do to smuggle an
                              unnecessary cast into their code. But casts should never become routine
                              parts of coding. They indicate that there is something out of the
                              ordinary going on. The simplest, clearest, and most reusable solution to
                              the original problem (remember that?) is the one I started with: turn
                              off the warning.

                              --

                              Pete Becker
                              Dinkumware, Ltd. (http://www.dinkumware.com)

                              Comment

                              Working...