views:

123

answers:

4

I am trying to get some C++ code originally written in Microsoft Visual Studio (VS) 2003 to compile under VS 2008 and I am having trouble finding an efficient solution to assigning a vector::iterator to the beginning of a char array. I know that iterators went from being a defined as a simple pointer type (T*) to a class type between VS 2003 and VS 2005. Here is a simple example of what I am talking about:

typedef std::vector<char>       CharContainer;
typedef CharContainer::iterator InputIt;

int FindNumMsgs( InputIt _inputIter, int _len );

int ProcessBufferForMsgs( char buf[], const size_t maxlen )
{
    int numMsgs = FindNumMsgs( InputIt(buf), maxlen );
    ...
}

So, in VS 2003, this compiles and works with no problem (since iterators are defined as T*). In VS 2008, this errors with C2440 (function-style-cast) since I can no longer just assign the iterator with the buf pointer. What would I do to get this to work in VS 2008 now that iterators are a class type? I could copy the buffer into a vector, then pass in myVec.begin(), but I have to think that I can avoid this overhead.

A: 

If FindNumMsgs accepts char* as the first parameter, maybe you could just use a simple char* pointer:

int ProcessBufferForMsgs( char buf[], const size_t maxlen )
{
    char* simpleIterator = buf;
    int numMsgs = FindNumMsgs( simpleIterator, maxlen );
    ...
}
AraK
Actually, buf is already a pointer in that context.
sellibitze
The first arg in FindNumMsgs is a vector<char>::iterator.
Jason Bard
A: 

What's the signature of FindNumMsgs? If it takes a char* you can just replace InputIt(buf) with buf. If it doesn't, there's little you can do about it without changing FindNumMsgs.

sellibitze
Well, FindNumMsgs takes a vector<char>::iterator as the first argument. The whole point of this question is to avoid changing the function call, which does more than my simple example implies.
Jason Bard
I only see two options: (1) Turn FindNumMsgs into a template (accepting arbitraty iterators) or overload it with a char* or const char* parameter. (2) Copy your buffer to a vector and use the vector's iterator.
sellibitze
A: 

Time to refactor. You need to change FindNumMsgs to take a (const?) char * as input, or maybe provide a second overloaded version. Better yet make it a templatized function that takes a begin/end pair of anything with iterator or pointer semantics.

Mark Ransom
Well, there are a bunch of functions that would have to be refactored and quite frankly, templatization would be overkill here. Again, I could just copy the buffer into a vector, pass in it's .begin() operator and be on my merry way, but I feel that there has to be a way to do this without having to do a copy.
Jason Bard
Sometimes I feel like the commercial where the guy is on his lawn mower and says "I'm in debt up to my eyeballs!" :-) I am mainly just trying to figure out if one can still use iterators directly on an array, without actually copying it into a container.
Jason Bard
Of course, whether you *should* do that is another story altogether...
Jason Bard
It depends on the implementation of vector<T>::iterator. In any case you really shouldn't bother packaging a pointer into a vector<T>::iterator. And this "should" really means don't try it. If you're too lazy to change anything you still could try to compile your code in release mode.
sellibitze
+1  A: 

The proper solution would be to template FindNumMsgs such that it can work with either iterators or pointers (since pointers can be used as iterators just fine). Something like this:

template <class T>
int FindNumMsgs(T it, int count) {
    while(count--) {
        // do whatever
        it++;
    }
    return n;
}
Evan Teran
The standard library prefers to use begin,end as parameters rather than begin,count. I would follow their lead. You can always use begin+count in the function call.
Mark Ransom
true enough, but i wanted to offer a solution which is consistant with his existing code.
Evan Teran
but, lets not forget about `fill_n` and similar ;-).
Evan Teran
After looking at all the code that will be affected, I decided that this was the best solution. Thanks Evan and props to Mark as well.
Jason Bard