Well, I'm late, I know, still I want to point out another possibility, if you want to completely hide away the internals of class B:
class A
{
private:
class B;
std::set<B*> b_set;
};
Notice using pointers in the set. However, there is yet left an important difference: as only pointers are inserted, you can still insert pointers to different instances having the same content. To solve this, you need a custom comparator:
class A
{
private:
class B;
struct Less
{
bool operator() (B const* x, B const* y) const
{
return *x < *y;
}
};
std::set<B*, Less> b_set;
};
Be aware (this was not mentioned in the previous answer, but is required there, too!) that there must be defined a comparator for B (B or reference to, not pointer!):
A.h
#include <set>
class A
{
private:
class B;
struct Less
{
bool operator() (B const* x, B const* y) const;
};
std::set<B*, Less> b_set;
};
A.cpp
class A::B
{
friend bool Less::operator() (B const* x, B const* y) const;
bool operator<(B const& other) const
{
return foo < other.foo;
}
int foo;
};
bool A::Less::operator() (B const* x, B const* y) const
{
return *x < *y;
}
This allows to hide away B completely from the header, if you want or need to for any reason. However, you cannot insert objects from the stack directly any more, as they are not copied and you have pointers to the stack that quickly get invalid. Special care has to be taken for deleting the objects when they are not needed any more, or you get memory leaks. Remember that there is no garbage collection as you know from Java. If using C++11, you can alleviate the problem using ::std::unique_ptr, before, ::std::auto_ptr:
A.h
#include <set>
#include <memory>
class A
{
private:
class B;
struct Less
{
bool operator() (B const* x, B const* y) const;
};
std::set<std::unique_ptr<B>, Less> b_set;
};