Click to See Complete Forum and Search --> : Problem with Iterators and Vectors


InTheFlatField
July 16th, 2008, 01:52 AM
I'm working on learning the STL and I'm trying to use an iterator to move through a vector, a pretty standard thing to do. I've followed the examples I've seen but I get compiler error I'm not familiar with:

g++ -Wall -O2 -c -o Archive.o Archive.cc
Archive.cc: In member function 'bool Archive::WriteArchiveFile(const std::string&, const std::vector<ArchiveFileHeader, std::allocator<ArchiveFileHeader> >&)':
Archive.cc:43: error: no match for 'operator=' in 'iter = ((const std::vector<ArchiveFileHeader, std::allocator<ArchiveFileHeader> >*)files)->std::vector<_Tp, _Alloc>::begin [with _Tp = ArchiveFileHeader, _Alloc = std::allocator<ArchiveFileHeader>]()'
/usr/include/c++/4.2/bits/stl_iterator.h:637: note: candidates are: __gnu_cxx::__normal_iterator<ArchiveFileHeader*, std::vector<ArchiveFileHeader, std::allocator<ArchiveFileHeader> > >& __gnu_cxx::__normal_iterator<ArchiveFileHeader*, std::vector<ArchiveFileHeader, std::allocator<ArchiveFileHeader> > >::operator=(const __gnu_cxx::__normal_iterator<ArchiveFileHeader*, std::vector<ArchiveFileHeader, std::allocator<ArchiveFileHeader> > >&)
make: *** [Archive.o] Error 1


Here's the two relevant source code files:

Archive.hh
#ifndef ARCHIVE_HH_
#define ARCHIVE_HH_

#include <vector>
#include <string>
#include "File.hh"
#include "ArchiveHeaders.hh"

class Archive
{
public:
Archive();
~Archive();

bool WriteArchiveFile( const std::string &archiveName, const std::vector<ArchiveFileHeader> &files );

private:
static const char ARCHIVE_ID[]; // The name put at the start of an archive.


std::vector<ArchiveFileHeader> m_headers;
};

#endif


Archive.cc
#include "Archive.hh"

const char Archive::ARCHIVE_ID[] = "TestArchive"; // You can change this to any string less than STR_LEN.

Archive::Archive() {}

Archive::~Archive() {}

bool Archive::WriteArchiveFile( const std::string &archiveName, const std::vector<ArchiveFileHeader> &files )
{
if ( ( files.size() <= 0 ) || ( archiveName.empty() ) )
{
return false;
}

FileOutputStream fileOut;

if ( ! fileOut.OpenFile( archiveName, binary ) )
{
return false;
}

ArchiveHeader archiveHeader;

archiveHeader.SetID( ARCHIVE_ID );

archiveHeader.SetTotalFiles( files.size() );

fileOut.Write( ( char* )&archiveHeader, sizeof( ArchiveHeader ) );

int currentOffset = 0;

currentOffset += sizeof( ArchiveHeader );

std::vector<ArchiveFileHeader>::iterator iter;

iter = files.begin();

return true;
}


I'm still pretty new to the STL and just learned about iterators today. I'm sure it's some silly error on my part but I can't see it for the life of me.

Any help in the matter is greatly appreciated.

I didn't post the other source code files in the interest of keeping this post at a reasonable size. If you need them, ask and I can post them too.

souldog
July 16th, 2008, 03:01 AM
did not read to closely, but your files vector is passed by constant reference
so you will need to use a constant iterator

std::vector<ArchiveFileHeader>::const_iterator iter(files.begin());

InTheFlatField
July 16th, 2008, 03:11 AM
Thanks, your right. I didn't think to look in the declaration of the vector.

But since I need to loop through the files vector with a traditional

for ( iter = file.begin(); iter = files.end(); ++iter ) {}

I'm assuming I can't use a iter_const so I will have to make the files vector not const.

Thanks again.

souldog
July 16th, 2008, 03:16 AM
I threw const in front of the iterator declaration but got compilation errors.


if by this you mean

const std::vector<ArchiveFileHeader>::iterator iter;

them that is wrong

It should be

std::vector<ArchiveFileHeader>::const_iterator iter;

InTheFlatField
July 16th, 2008, 03:19 AM
Sorry, updated my post above.

GNiewerth
July 16th, 2008, 03:21 AM
Since you passed a const reference you´re not allowed to change the vector, so you have to use a const iterator:


std::vector<ArchiveFileHeader>::const_iterator iter;

iter = files.begin();


Looks like souldog was a bit faster than me ;)

souldog
July 16th, 2008, 03:33 AM
you can loop through the fields with a constant iterator, you just can't modify the elements of the vector.

By the way, you can also do this with a normal loop


for(size_t i = 0; i < files.size(); i++)
{
//use files[i].
}