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

Discussion in 'C++' started by Anonymous, Mar 28, 2005.

  1. Anonymous

    Anonymous Guest

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


    std::vector<double> src;
    std::vector<int> dest;

    std::vector<double>::size_type size = src.size();
    dest.reserve(size);
    for (std::vector<int>::size_type i = 0;
    i < size;
    i++)
    {
    dest = static_cast<int>(src);
    }
     
    Anonymous, Mar 28, 2005
    #1
    1. Advertising

  2. "Anonymous" <> wrote in message
    news:...

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


    > std::vector<double> src;
    > std::vector<int> dest;
    >
    > std::vector<double>::size_type size = src.size();
    > dest.reserve(size);
    > for (std::vector<int>::size_type i = 0;
    > i < size;
    > i++)
    > {
    > dest = static_cast<int>(src);
    > }


    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.
     
    Andrew Koenig, Mar 28, 2005
    #2
    1. Advertising

  3. Andrew Koenig schrieb:
    > "Anonymous" <> wrote in message
    > news:...
    >
    >
    >>Is there a non-brute force method of doing this?
    >>transform() looked likely but had no predefined function object.

    >
    >
    >>std::vector<double> src;
    >>std::vector<int> dest;
    >>
    >>std::vector<double>::size_type size = src.size();
    >>dest.reserve(size);
    >>for (std::vector<int>::size_type i = 0;
    >> i < size;
    >> i++)
    >>{
    >> dest = static_cast<int>(src);
    >>}

    >
    >
    > 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.


    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(_RandomAccessIter, _RandomAccessIter,
    _OutputIter, std::random_access_iterator_tag) [with _RandomAccessIter =
    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_aux2(_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::__normal_iterator<double*, std::vector<double,
    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(_InputIter, _InputIter,
    _OutputIter) [with _InputIter = __gnu_cxx::__normal_iterator<double*,
    std::vector<double, std::allocator<double> > >, _OutputIter = int*]'
    /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_uninitialized.h:76:
    instantiated from `_ForwardIter
    std::__uninitialized_copy_aux(_InputIter, _InputIter, _ForwardIter,
    __true_type) [with _InputIter = __gnu_cxx::__normal_iterator<double*,
    std::vector<double, std::allocator<double> > >, _ForwardIter = int*]'
    /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_uninitialized.h:112:
    instantiated from `_ForwardIter std::uninitialized_copy(_InputIter,
    _InputIter, _ForwardIter) [with _InputIter =
    __gnu_cxx::__normal_iterator<double*, std::vector<double,
    std::allocator<double> > >, _ForwardIter = int*]'
    /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/include/g++-v3/bits/stl_vector.h:829:
    instantiated from `void std::vector<_Tp,
    _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator,
    std::forward_iterator_tag) [with _ForwardIterator =
    __gnu_cxx::__normal_iterator<double*, std::vector<double,
    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:807:
    instantiated from `void std::vector<_Tp,
    _Alloc>::_M_initialize_dispatch(_InputIter, _InputIter, __false_type)
    [with _InputIter = __gnu_cxx::__normal_iterator<double*,
    std::vector<double, 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:289:
    instantiated from `std::vector<_Tp, _Alloc>::vector(_InputIterator,
    _InputIterator, typename std::_Vector_base<_Tp,
    _Alloc>::allocator_type&) [with _InputIterator =
    __gnu_cxx::__normal_iterator<double*, std::vector<double,
    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
     
    Malte Starostik, Mar 28, 2005
    #3
  4. On 2005-03-28, Anonymous <> wrote:
    > Is there a non-brute force method of doing this?
    > transform() looked likely but had no predefined function object.


    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
    http://pegasus.rutgers.edu/~elflord/
     
    Donovan Rebbechi, Mar 28, 2005
    #4
  5. Donovan Rebbechi schrieb:
    > On 2005-03-28, Anonymous <> wrote:
    >
    >>Is there a non-brute force method of doing this?
    >>transform() looked likely but had no predefined function object.

    >
    >
    > 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.


    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
     
    Malte Starostik, Mar 28, 2005
    #5
  6. Anonymous

    Pete Becker Guest

    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.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Mar 28, 2005
    #6
  7. Anonymous

    Pete Becker Guest

    Donovan Rebbechi wrote:

    >
    > 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.
    >


    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)
     
    Pete Becker, Mar 28, 2005
    #7
  8. On 2005-03-28, Pete Becker <> wrote:
    > Donovan Rebbechi wrote:
    >
    >>
    >> 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.
    >>

    >
    > 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.


    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
    http://pegasus.rutgers.edu/~elflord/
     
    Donovan Rebbechi, Mar 28, 2005
    #8
  9. Anonymous

    Pete Becker Guest

    Donovan Rebbechi wrote:

    > On 2005-03-28, Pete Becker <> wrote:
    >
    >>Donovan Rebbechi wrote:
    >>
    >>
    >>>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.
    >>>

    >>
    >>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.

    >
    >
    > 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.


    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.

    > Writing a small wrapper around static_cast is a minor inconvenience at worst.\


    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>

    > Of course you understand this -- so how would you go about managing the
    > problem of noisy warnings ?


    Turn 'em off.

    >
    > 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 ?
    >


    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 "Controlling 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)
     
    Pete Becker, Mar 28, 2005
    #9
  10. 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:
    > On 2005-03-28, Pete Becker <> wrote:
    >
    >>Donovan Rebbechi wrote:
    >>
    >>
    >>>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.
    >>>

    >>
    >>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.

    >
    >
    > 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,
     
    Yuriy Solodkyy, Mar 28, 2005
    #10
  11. Anonymous

    Duane Hebert Guest

    "Pete Becker" <> wrote in message news:...
    > 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.


    Or just use a static_cast.
     
    Duane Hebert, Mar 28, 2005
    #11
  12. Anonymous

    Pete Becker Guest

    Duane Hebert wrote:
    > "Pete Becker" <> wrote in message news:...
    >
    >>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.

    >
    >
    > Or just use a static_cast.
    >
    >


    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)
     
    Pete Becker, Mar 28, 2005
    #12
  13. Anonymous

    Howard Guest

    "Pete Becker" <> wrote in message
    news:...


    >
    > Tom DeMarco, in a book called "Controlling 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.
    >


    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
     
    Howard, Mar 28, 2005
    #13
  14. In article <>,
    Pete Becker <> wrote:

    > Duane Hebert wrote:
    > > "Pete Becker" <> wrote in message
    > > news:...
    > >
    > >>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.

    > >
    > >
    > > Or just use a static_cast.
    > >
    > >

    >
    > 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.


    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_type value_type;
    value_type operator () (const From& f) const
    {return static_cast<value_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>::iterator,
    vector<double>::iterator
    >
    > It;

    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
     
    Howard Hinnant, Mar 28, 2005
    #14
  15. Anonymous

    Pete Becker Guest

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


    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)
     
    Pete Becker, Mar 28, 2005
    #15
  16. Pete Becker wrote:
    > Howard Hinnant wrote:
    >
    >>
    >> Or instead maybe write a templated "casting iterator" which would
    >> certainly be more trouble up front, but more reusable down the road.
    >>

    >
    > 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.
    >


    I fail to see how this is an unnecessary cast. What you are doing is casting,
    whether implicitly or explicitly. And I'd much rather keep the warning on so
    that if for some reason I mistakenly try to assign a double to an int in the
    wrong place, I'm warned about it.
     
    Kurt Stutsman, Mar 29, 2005
    #16
  17. Anonymous

    Pete Becker Guest

    Kurt Stutsman wrote:

    >
    > I fail to see how this is an unnecessary cast. What you are doing is
    > casting, whether implicitly or explicitly.


    A cast is something you write in your source code; there is no such
    thing as an implicit cast. What you're talking about is a conversion.
    The compiler will do the conversion, with or without the cast. You don't
    need it to make your code correct. You need it to make the compiler shut
    up about code that's well defined and meaningful.

    > And I'd much rather keep the
    > warning on so that if for some reason I mistakenly try to assign a
    > double to an int in the wrong place, I'm warned about it.


    And, as I'm getting tired of saying, this "safety" is illusory. If
    you're not paying attention to what you're doing you're going to make
    mistakes. Warnings may catch some carelessness, but not all. If you
    don't trust yourself to write code that's correct, take a break and
    start fresh later.

    Writing five lines of code instead of one just to tell the compiler that
    I know how to write valid C++ code doesn't strike me as a good use of my
    time.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Mar 29, 2005
    #17
  18. Yuriy Solodkyy wrote:

    > 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).


    In that case, surely someone will write a compiler that check if the
    programmer seems to really knows what is doing when using that pragma and
    emits a warning if the check fails.

    --
    Salu2
     
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Mar 29, 2005
    #18
  19. Pete Becker wrote:
    > Kurt Stutsman wrote:
    >
    >>
    >> I fail to see how this is an unnecessary cast. What you are doing is
    >> casting, whether implicitly or explicitly.

    >
    >
    > A cast is something you write in your source code; there is no such
    > thing as an implicit cast. What you're talking about is a conversion.
    > The compiler will do the conversion, with or without the cast. You don't
    > need it to make your code correct. You need it to make the compiler shut
    > up about code that's well defined and meaningful.
    >

    Fine, I misdescribed it as casting instead of implicit conversion. You are
    still converting it from one type to another that cannot support the same
    values (3.6 to an int will not give you 3.6 obviously). If I'm going to do
    something that loses information, I personally prefer to have something
    explicitly describing that (like a static_cast<>).

    > And, as I'm getting tired of saying, this "safety" is illusory. If
    > you're not paying attention to what you're doing you're going to make
    > mistakes. Warnings may catch some carelessness, but not all. If you
    > don't trust yourself to write code that's correct, take a break and
    > start fresh later.


    I don't think anyone writes completely perfect code all the time. We are,
    after all, human. We also write very large code bases from time to time or use
    other people's libraries in addition our own. It's possible we might make a
    mistake during all this perfect code writing. A warning about it at compile
    time sure is nicer than trying to find why something is not working because
    I'm losing a 0.6 by mistake somewhere.

    >
    > Writing five lines of code instead of one just to tell the compiler that
    > I know how to write valid C++ code doesn't strike me as a good use of my
    > time.
    >


    And using templates you write this 5 lines of code once. That's some pretty
    precious time.
     
    Kurt Stutsman, Mar 30, 2005
    #19
  20. Anonymous

    Pete Becker Guest

    Kurt Stutsman wrote:
    >
    > And using templates you write this 5 lines of code once. That's some
    > pretty precious time.
    >


    And you compile it every time you use it. Pretty soon you find that all
    these wonderful templates are killing your turnaround times, and
    sometimes your compiler.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Mar 30, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sydex
    Replies:
    12
    Views:
    6,601
    Victor Bazarov
    Feb 17, 2005
  2. Ingo Nolden
    Replies:
    15
    Views:
    1,542
    Jerry Coffin
    Apr 30, 2005
  3. Schnoffos
    Replies:
    2
    Views:
    1,246
    Martien Verbruggen
    Jun 27, 2003
  4. Replies:
    3
    Views:
    3,176
  5. Shriramana Sharma
    Replies:
    8
    Views:
    290
    Gerhard Fiedler
    Jun 18, 2013
Loading...

Share This Page