Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Compilation error when using a std::vector iterator

81 views
Skip to first unread message

Mark

unread,
Oct 6, 2015, 6:05:17 AM10/6/15
to
I am trying to build some legacy C++ code. Much of the code uses the
std::vector class and fails to compile. I have created a simple
example which also gives the same error:

-------------------------------------------------
#include <vector>

using std::vector;

class TestMessage
{
protected:
char dummy[41];
};

class TestLink
{
public:
typedef vector<TestMessage*> TestMsgVector;
typedef TestMsgVector::iterator TestVectorIter;
};

void doIt(const TestLink::TestMsgVector* pVector)
{
for (TestLink::TestVectorIter iter = pVector->begin(); // Compiler
error here!
iter != pVector->end(); ++iter)
{}
}

int main()
{
TestLink::TestMsgVector vector;
doIt(&vector);
}
-------------------------------------------------

Error message:
test.cpp: In function void doIt(const TestLink::TestMsgVector*):
test.cpp:20: error: conversion from
__gnu_cxx::__normal_iterator<TestMessage* const*,
std::vector<TestMessage*, std::allocator<TestMessage*> > > to
non-scalar type TestLink::TestVectorIter requested

What's wrong with this? And how to fix it?

touc

unread,
Oct 6, 2015, 7:05:56 AM10/6/15
to
On 06/10/15 11:04, Mark wrote:
> I am trying to build some legacy C++ code. Much of the code uses the
> std::vector class and fails to compile. I have created a simple
> example which also gives the same error:
>
> -------------------------------------------------
> ...
> {
> public:
> typedef vector<TestMessage*> TestMsgVector;
> typedef TestMsgVector::iterator TestVectorIter;
> };
>
> void doIt(const TestLink::TestMsgVector* pVector)
> {
> ...
> What's wrong with this? And how to fix it?
>

It looks like a const mismatch, perhaps your iterator should be:

typedef TestMsgVector::const_iterator TestVectorIter;


guinne...@gmail.com

unread,
Oct 6, 2015, 7:07:13 AM10/6/15
to
pVector is a pointer to const object. The only member functions
that can be called on such an object are the const-qualified ones.

vector<> defines two overloads of member function begin() (and end()):
- A non-qualified one that returns a vector<>::iterator;
- A const-qualified one that returns a vector<>::const_iterator.

Your code calls the second one (since *pVector is const). You
cannot directly assign a const_iterator to an iterator.

If the code in the loop will not modify any elements in the vector,
change the second typedef in TestLink to name the TestMessageVector's
const_iterator type, not iterator.

If that code needs to actually modify elements in the vector,
drop the 'const' from the parameter declaration of pVector.

Öö Tiib

unread,
Oct 6, 2015, 7:09:08 AM10/6/15
to
On Tuesday, 6 October 2015 13:05:17 UTC+3, Mark wrote:
> I am trying to build some legacy C++ code.

Bjarne added 'const' to C++ 1981, it was initially called
'readonly'. Looks like legacy code from some alternative
universe.

> Much of the code uses the
> std::vector class and fails to compile. I have created a simple
> example which also gives the same error:
>
> -------------------------------------------------
> #include <vector>
>
> using std::vector;
>
> class TestMessage
> {
> protected:
> char dummy[41];
> };
>
> class TestLink
> {
> public:
> typedef vector<TestMessage*> TestMsgVector;
> typedef TestMsgVector::iterator TestVectorIter;

That is 'iterator'.

> };
>
> void doIt(const TestLink::TestMsgVector* pVector)

That 'const TestLink::TestMsgVector*' causes that only 'const'
members are callable.

> {
> for (TestLink::TestVectorIter iter = pVector->begin(); // Compiler
> error here!

That 'iter' is 'iterator', 'begin() const' returns 'const_iterator' and
there are no conversions from 'const_iterator' to 'iterator'.

> iter != pVector->end(); ++iter)
> {}
> }
>
> int main()
> {
> TestLink::TestMsgVector vector;
> doIt(&vector);
> }
> -------------------------------------------------
>
> Error message:
> test.cpp: In function void doIt(const TestLink::TestMsgVector*):
> test.cpp:20: error: conversion from
> __gnu_cxx::__normal_iterator<TestMessage* const*,
> std::vector<TestMessage*, std::allocator<TestMessage*> > > to
> non-scalar type TestLink::TestVectorIter requested
>
> What's wrong with this? And how to fix it?

Compiler wrote same thing what I wrote above but unfortunately the
implementation details of standard library somewhat hide it in error
message.

To fix it you must be clear if you need 'const_iterator' or
'iterator'. The 'iterator' does convert to 'const_iterator' but not
other way around.

Mark

unread,
Oct 6, 2015, 8:01:36 AM10/6/15
to
Great :-) That's it. Thanks.

Jorgen Grahn

unread,
Oct 6, 2015, 12:27:28 PM10/6/15
to
I wonder why it ever compiled -- if it did. Your use of the word
"legacy" above sounds to me as a hint that it once did ... but I
cannot think of a way that a standard library or compiler would allow
it.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Mark

unread,
Oct 7, 2015, 2:49:20 AM10/7/15
to
On 6 Oct 2015 16:27:06 GMT, Jorgen Grahn <grahn...@snipabacken.se>
wrote:
I can't answer this. This is my first involvement in this code but,
like you, assume it once did compile -- but with a different compiler
on a different OS.

Jorgen Grahn

unread,
Oct 7, 2015, 5:03:07 AM10/7/15
to
On Wed, 2015-10-07, Mark wrote:
> On 6 Oct 2015 16:27:06 GMT, Jorgen Grahn <grahn...@snipabacken.se>
> wrote:
>
>>On Tue, 2015-10-06, Mark wrote:
>>> On Tue, 6 Oct 2015 12:05:38 +0100, touc <n...@thebainbridges.me> wrote:
>>>
>>>>On 06/10/15 11:04, Mark wrote:
>>>> > I am trying to build some legacy C++ code. Much of the code uses the
>>>> > std::vector class and fails to compile. I have created a simple
>>>> > example which also gives the same error:

...

>>I wonder why it ever compiled -- if it did. Your use of the word
>>"legacy" above sounds to me as a hint that it once did ... but I
>>cannot think of a way that a standard library or compiler would allow
>>it.
>
> I can't answer this. This is my first involvement in this code but,
> like you, assume it once did compile -- but with a different compiler
> on a different OS.

Well, I /both/ assume it did -- and at the same time cannot think of
any circumstances where that could happen!

Can anyone else here?

(To me it's just an intellectual exercise, but I guess that if the
code never did compile, that would be important information for you
... perhaps you got the wrong version of the code?)

Mark

unread,
Oct 7, 2015, 6:27:47 AM10/7/15
to
On 7 Oct 2015 09:02:50 GMT, Jorgen Grahn <grahn...@snipabacken.se>
wrote:

>On Wed, 2015-10-07, Mark wrote:
>> On 6 Oct 2015 16:27:06 GMT, Jorgen Grahn <grahn...@snipabacken.se>
>> wrote:
>>
>>>On Tue, 2015-10-06, Mark wrote:
>>>> On Tue, 6 Oct 2015 12:05:38 +0100, touc <n...@thebainbridges.me> wrote:
>>>>
>>>>>On 06/10/15 11:04, Mark wrote:
>>>>> > I am trying to build some legacy C++ code. Much of the code uses the
>>>>> > std::vector class and fails to compile. I have created a simple
>>>>> > example which also gives the same error:
>
>...
>
>>>I wonder why it ever compiled -- if it did. Your use of the word
>>>"legacy" above sounds to me as a hint that it once did ... but I
>>>cannot think of a way that a standard library or compiler would allow
>>>it.
>>
>> I can't answer this. This is my first involvement in this code but,
>> like you, assume it once did compile -- but with a different compiler
>> on a different OS.
>
>Well, I /both/ assume it did -- and at the same time cannot think of
>any circumstances where that could happen!
>
>Can anyone else here?
>
>(To me it's just an intellectual exercise, but I guess that if the
>code never did compile, that would be important information for you
>... perhaps you got the wrong version of the code?)

I've just tried it with Sun C++ 5.8 Patch 121017-14 on Solaris 5.10
and it did compile!
--
(\__/) M.
(='.'=) If a man stands in a forest and no woman is around
(")_(") is he still wrong?

Jorgen Grahn

unread,
Oct 7, 2015, 12:40:41 PM10/7/15
to
Weird! So then this obviously broken code compiles too?

#include <vector>
void foo(const std::vector<int>& v)
{
if(v.empty()) return;
std::vector<int>::iterator i = v.begin();
*i = 42;
}

I seem to recall that Sun had a low-quality standard library and that
people often used a third-party replacement, but that was a decade ago
...

Vir Campestris

unread,
Oct 7, 2015, 4:56:45 PM10/7/15
to
On 07/10/2015 17:40, Jorgen Grahn wrote:
> I seem to recall that Sun had a low-quality standard library and that
> people often used a third-party replacement, but that was a decade ago

That rings a bell. I have a vague feeling that _ages_ ago Microsoft had
a library where iterator and const_iterator were typedefs of the same thing.

Andy

Mark

unread,
Oct 8, 2015, 3:27:44 AM10/8/15
to
On 7 Oct 2015 16:40:12 GMT, Jorgen Grahn <grahn...@snipabacken.se>
This doesn't compile:
Error: Cannot use const int* to initialize int*.

Jorgen Grahn

unread,
Oct 8, 2015, 1:15:02 PM10/8/15
to
With Sun C++, the one that accepted your first piece of code?

/That/ I didn't expect: the code above was supposed to trigger the
same bug as yours. I just removed the typedefs and classes and
pointers which obscured the problem a bit.

The message you get (must be on the v.begin() line, right?) seems to
indicate that their std::vector<T>::iterator is just a fancy name for
T*. So at least we know that the std::vector you use there is not of
the best quality ... I don't think it's illegal in any way to define
the iterator like that, but it's more polite to the programmer to make
it a distinct type.

Mark

unread,
Oct 8, 2015, 2:08:17 PM10/8/15
to
On 8 Oct 2015 17:14:26 GMT, Jorgen Grahn <grahn...@snipabacken.se>
Yep. The same compiler.

>/That/ I didn't expect: the code above was supposed to trigger the
>same bug as yours. I just removed the typedefs and classes and
>pointers which obscured the problem a bit.
>
>The message you get (must be on the v.begin() line, right?)

Yes.

>seems to
>indicate that their std::vector<T>::iterator is just a fancy name for
>T*. So at least we know that the std::vector you use there is not of
>the best quality ... I don't think it's illegal in any way to define
>the iterator like that, but it's more polite to the programmer to make
>it a distinct type.

TBH some of the subleties of this escape me ATM.

0 new messages