tags:

views:

205

answers:

3

I have made a string vector

vector<string> actor_;

and then added elements in it using push_back.

I now want to display all of them, for which I need to run a loop according to the number of elements in the vector. For that, I need to run the following loop:

for (int i = 0; i < (int)actor_.size; i++)
{
}

but this returns the following error:


error C2440: 'type cast' : cannot convert from 'unsigned int (__thiscall std::vector<_Ty>::* )(void) const' to 'int'
1>        with
1>        [
1>            _Ty=std::string
1>        ]
1>        There is no context in which this conversion is possible

+6  A: 

size is a member function; you mean:

for (unsigned int i = 0; i < actor_.size(); i++) { }

(it's a good idea to use std::size_t instead of unsigned int as well)

James McNellis
oh, silly me...its now working.Question: why is std::size_t a better idea than unsigned int?
xbonez
@James: Just to clarify, he never had `unsigned int` to begin with. (Maybe I'm reading to much into it.) @xbonez: `size_t` is the standard integral type for measuring the size of something, and could very well be bigger than an `unsigned`. `size()` returns a `size_t`, and so you should use a `size_t` to match.
GMan
because size_t will always have the same type as the return type of the size() function, whatever the arch/platform you are compiling to (x86, x86_64, etc..)
Gabriel Cuvillier
@GMan: I changed it from `int` to `unsigned` because `int` would likely give a signed/unsigned comparison warning. I guess I could have just changed it to `size_t`, but I didn't think of that at first...
James McNellis
Technically, `std::vector<>::size()` returns `std::vector<>::size_type` , which in theory _could_ be something other than `size_t`. In practice, I don't know of any implementation where it's not `size_t`.
Adrian McCarthy
@Gabriel: I changed a lot of `unsigned int`s to `size_t`s when modifying our software to 64 bits. We have some large data structures, which is why the changeover was necessary.
David Thornley
@GMan: I've read several sources that claim `std::vector<>::size_type` is "implementation defined".
Adrian McCarthy
@Adrian: you're right, just as `size_t` and `int` are.
MSalters
The error casting from unsigned int would appear to be a result of the attempt to cast the function pointer to an int - as in "(int)actor_.size". Presumably this is compiled for a 32-bit architecture.
Steven Mackenzie
@Adrian: You are right, it only says it has to be an unsigned integral type.
GMan
+2  A: 

You might want to consider using an iterator rather than relying on operator[] to access the elements (as implied by you using an integral loop counter and size()). This would allow you to change the container type in the future should you so wish without having to modify your access code.

TheJuice
A: 

The most correct would be:

for (std::vector<std::string>::size_type i = 0; i < actor_.size(); ++i) {}

That's ugly. You can simplify it with a typedef.

C++0x gives us auto, but that's easy to misuse:

for (auto i = 0; i < actor_.size() ++i) {}  // WRONG

Here again, i is an int (because 0 is an int), which means we haven't solved the problem. Iterators plus auto yield something reasonable:

for (auto it = actor_.begin(); it != actor_.end(); ++it) {}

Another option would be to use std::for_each and a lambda. STL syntax almost always favors iterators over indexes.

Oh, and GMan pointed out that C++0x makes this even easier with range-based for loops:

for (auto& a : actor_) {}
Adrian McCarthy
If we're talking C++0x, I'd prefer: `for ( auto` Ah, so simple.
GMan