There is the following class B derived from std::vector
class B: public std::vector <unsigned int>
{
public:
B() : std::vector <unsigned int> ( 0 ) {}
};
and a class A witten as follows:
class A
{
private:
B b;
double x;
public:
B & getB () {return b;}
B const & getB() const {return b;}
bool operator() ( const A & a ) const
{
return a < a.x;
}
};
Why it is impossible to return a refererence to the variable b of some object A stored in std::list from its iterator (and how to do that)?
int main ()
{
std::set <A > alist;
std::set <A> ::iterator i_alist = alist.begin();
for (; i_alist != alist.end(); i_list++)
{
B &il = (*i_alist).getB(); //Compiler error
B &il2 = i_alist->getB(); //Compiler error
il.push_back(10); //Modify il and concurrently B
}
}
Compiler error:
Error 1 error C2440: 'initializing' : cannot convert from 'const B' to 'B &' d:\test.cpp
Thanks for your help…
Edit question:
The possible solution using const_cast :
B &il2 = const_cast <B&> ( i_alist->getB() );
This has very little to do with
std::vectorand everything to do withstd::set. You store your objects in astd::set. Elements ofstd::setare not modifiable from the outside. Once you inserted an element into a set, you cannot change it.For this reason,
std::set::iteratormight (and will) evaluate to a constant object, even if it is not aconst_iterator(the language specification actually allowsstd::set::iteratorandstd::set::const_iteratorto refer to the same type, but does not require it). I.e. in your example*i_listis a const-qualified object of typeconst A. The compiler will call theconstversion ofgetB, which returnsconst B &. You are apparently hoping to break through that constness, expecting the non-const version ofgetBto be called.There’s no way around it, unless you decide to use some sort of hack (
const_castetc.) to remove the constness from the set element and thus make the compiler to call non-const version ofgetB.The
const_cast-based hack-solution would look asor you can remove the constness later, from the returned
Breference