Const iterator, private struct.

S

swhite

Hi,

Sorry, not very clear from the title but wasn't sure what to call it.
I was experimenting with the following in GCC 4.0.1 and didn't achieve
what I expected. I was trying to keep the internal class private, to
prevent creation, but also in the hope it might achieve something like
when you use "class <foo>;" to early declare to allow pointer passing,
but cannot access contents.

Also I passed out a const iterator containing this object expecting it
to make what it was iterating over const, but gcc allows me to change
it.

Just wondered what I should actually expect (found behaviour was
correct?) and anything close (if possible) to roughly achieve what I
was expecting.

#include <map>
#include <string>

class A
{
private:
struct Test
{
int a;
int b;
};
typedef std::map<std::string,Test *> Test2;

public:
typedef const Test2::const_iterator Test3;

private:
Test2 m_test;

public:
Test3 foo () { return m_test.end (); }
};

int main ()
{
A a;
A::Test3 test = a.foo ();
// Accesses object of private type...
// Didn't want, hoping for compiler error
int b = (*test).second->a;
(*test).second->a = 1; // modified const...
return 0;
}

Regards,
Simon
 
P

Pierre Barbier de Reuille

swhite said:
Hi,

Sorry, not very clear from the title but wasn't sure what to call it.
I was experimenting with the following in GCC 4.0.1 and didn't achieve
what I expected. I was trying to keep the internal class private, to
prevent creation, but also in the hope it might achieve something like
when you use "class <foo>;" to early declare to allow pointer passing,
but cannot access contents.

Also I passed out a const iterator containing this object expecting it
to make what it was iterating over const, but gcc allows me to change
it.

Just wondered what I should actually expect (found behaviour was
correct?) and anything close (if possible) to roughly achieve what I
was expecting.

#include <map>
#include <string>

class A
{
private:
struct Test
{
int a;
int b;
};
typedef std::map<std::string,Test *> Test2;

public:
typedef const Test2::const_iterator Test3;

private:
Test2 m_test;

public:
Test3 foo () { return m_test.end (); }
};

int main ()
{
A a;
A::Test3 test = a.foo ();
// Accesses object of private type...
// Didn't want, hoping for compiler error
int b = (*test).second->a;
(*test).second->a = 1; // modified const...
return 0;
}

Regards,
Simon

Well, the reason is const_iterator does not allow you to modify the
structure of the container, but it says nothing with regards to the
object themselves. To achieve what you want you need to do that:

#include <string>
#include <map>

class A
{
public:
struct Test
{
int a;
int b;
};
typedef std::map<std::string,const Test *> Test2;
typedef const Test2::const_iterator Test3;

Test3 foo () { return m_test.begin (); }
void add( const std::string& s, const Test& t )
{
m_test[ s ] = new Test( t );
}

void modify( const std::string& s, const Test& nt )
{
Test* t = const_cast<Test*>( m_test[ s ] );
*t = nt;
}
private:

Test2 m_test;

};

int main ()
{
A a;
A::Test t = {1,2};
a.add( "toto", t );
A::Test3 test = a.foo ();
// Accesses object of private type...
// Didn't want, hoping for compiler error
t.b = 1;
a.modify( "toto", t );
int b = test->second->a;
test->second->a = 1; // modified const...
return 0;
}

Pierre
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top