472,117 Members | 2,643 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,117 software developers and data experts.

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<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[i] = static_cast<int>(src[i]);
}
Jul 23 '05 #1
20 17113
"Anonymous" <in******@hotmail.com> wrote in message
news:in****************************@news-fe-03.texas.rr.com...
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[i] = static_cast<int>(src[i]);
}


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.
Jul 23 '05 #2
Andrew Koenig schrieb:
"Anonymous" <in******@hotmail.com> wrote in message
news:in****************************@news-fe-03.texas.rr.com...

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[i] = static_cast<int>(src[i]);
}

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
Jul 23 '05 #3
On 2005-03-28, Anonymous <in******@hotmail.com> 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/
Jul 23 '05 #4
Donovan Rebbechi schrieb:
On 2005-03-28, Anonymous <in******@hotmail.com> 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
Jul 23 '05 #5
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)
Jul 23 '05 #6
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)
Jul 23 '05 #7
On 2005-03-28, Pete Becker <pe********@acm.org> 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/
Jul 23 '05 #8
Donovan Rebbechi wrote:
On 2005-03-28, Pete Becker <pe********@acm.org> 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)
Jul 23 '05 #9
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 <pe********@acm.org> 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,


Jul 23 '05 #10

"Pete Becker" <pe********@acm.org> wrote in message news:O7********************@giganews.com...
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.
Jul 23 '05 #11
Duane Hebert wrote:
"Pete Becker" <pe********@acm.org> wrote in message news:O7********************@giganews.com...
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)
Jul 23 '05 #12

"Pete Becker" <pe********@acm.org> wrote in message
news:eZ********************@giganews.com...


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


Jul 23 '05 #13
In article <to********************@giganews.com>,
Pete Becker <pe********@acm.org> wrote:
Duane Hebert wrote:
"Pete Becker" <pe********@acm.org> wrote in message
news:O7********************@giganews.com...
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
Jul 23 '05 #14
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)
Jul 23 '05 #15
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.
Jul 23 '05 #16
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)
Jul 23 '05 #17
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
Jul 23 '05 #18
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.

Jul 23 '05 #19
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)
Jul 23 '05 #20
Kurt Stutsman wrote:
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.


No, you criticized what I said based on misunderstanding the terms that
I used.
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).
And 1/3 does not give you .3333 obviously. Where's the warning for this?
If I'm
going to do something that loses information, I personally prefer to
have something explicitly describing that (like a static_cast<>).


Okay, so instead of

int i = 1/3;

you advocate writing

int i = static_cast<int>(1/3);

so that you're explicitly describing it.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Ivan Paganini | last post: by
3 posts views Thread by Andreas Krueger | last post: by
1 post views Thread by Ingo Nolden | last post: by
2 posts views Thread by Pepijn Kenter | last post: by
1 post views Thread by perroe | last post: by
32 posts views Thread by T. Crane | last post: by
5 posts views Thread by jeremit0 | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.