std::list with const and non-const pointers - why aren't they typecompatible?

A

arijit79

Hi

I was just wondering if the return type of a function is
"std::list<const char *> &", then what could be the harm if I return
"std::list<char *>"?

All I am saying there is, I have a list of 'non-const' pointers,
please treat that as 'const' pointer and don't try to mess with the
content pointed.

To me, it makes complete sense and valid thinking. Not sure what am i
missing??

Any help??

Thanks
Arijit
 
A

Alf P. Steinbach

* (e-mail address removed):
I was just wondering if the return type of a function is
"std::list<const char *> &", then what could be the harm if I return
"std::list<char *>"?

That would allow you to change a constant object, like e.g.

char const* const s = "puck";

std::list<char*> varList;
std::list<char const*>& constList = varList; // !Not allowed

constList.push_back( s );
char* const p = *varList.begin();
p[0] = 'f';

All I am saying there is, I have a list of 'non-const' pointers,
please treat that as 'const' pointer and don't try to mess with the
content pointed.

To me, it makes complete sense and valid thinking. Not sure what am i
missing??

You're providing too little information to give any definite answer -- see the
FAQ about How To Post.

However, it does *seem* as if you're missing three important concepts and have
one misconception, none of them directly related to the 'const' issue:

* Probably missing, the concept of referring to something (via a pointer or
C++ reference doesn't matter in that respect). Reasons that it's probably
missing: having a list of raw pointers, returning a result by reference.

* Probably missing, the concept of object lifetime. Reason it's probably
missing: returning by reference.

* Probably missing, the concept of Return Value Optimization (RVO). Reason
it's probably missing: returning by reference.

* Probable misconception, that micro efficiency matters a lot. Reason it's
probably there: returning by reference, using a list of raw pointers.

If so the only cure is experience coupled with correct information (e.g. a good
book, or for that matter Usenet discussions).

But one doesn't always need to know the details of what's wrong in order to
suggest a cure.

In the only example you've given I suggest using std::list< std::string >, and
return that type directly (not tacking on a '&' at the end).


Cheers & hth.,

- Alf
 
A

arijit79

Thanks Alf.

To answer few of your concerns, let me take an example.

class X {

const std::list<const MyDS *> & getMyDSLst() const {
return _M_MyDS_list; // Err, I can't because my data member list
(see below) is not a list of const pointers. Here, I wanted to return
a const reference to this class's data member '_M_MyDS_list' *without*
any casting. So, I was wondering why I can't, and you clarified well,
thanks!
}

// Why not define the data member (below) as "std::list<const MyDS
*>"? Becasue I don't want to use casts for the mutating member
function 'alterMyDSListElementsforSomeReason()' below. So, I wanted to
retain my representation as mutable internally and provide the world
with a const list to const pointers in the 'get...' function above.

void alterMyDSListElementsforSomeReason();

// Why am I storing raw pointers? Because, MyDS is a base class from
which MyExtenededDS1, MyExtenededDS2, MyExtenededDS3, etc would be
extended. And my list '_M_MyDS_list' would actually store pointers to
those extended class objects, to maintain relative sequence among
those and polymorphism info.

private:
std::list<MyDS *> _M_MyDS_list;
};
 
A

arijit79

Basically, I am wondering, what is the recommended way to address all
these issues.
 
D

DerTopper

Hi

I was just wondering if the return type of a function is
"std::list<const char *> &", then what could be the harm if I return
"std::list<char *>"?

All I am saying there is, I have a list of 'non-const' pointers,
please treat that as 'const' pointer and don't try to mess with the
content pointed.

To me, it makes complete sense and valid thinking. Not sure what am i
missing??

That's fine, although the standard probably says that you'll get
undefined behaviour. I used a lot of code like the following:#

std::vector<DerivedClass*> SomeVector;

const std::vector<BaseClass*> ReturnSomething ()
{
return reinterpret_cast<BaseClass*> (SomeVector);
}

This works perfectly, since you only return a const vector of objects,
so you cannot break the vector by adding pointers of the wrong type.
Unfortunately, this kind of downcast is considered potentially harmful
by the compiler, since the involved (template) types
vector<BaseClass*> and vector<Derived*> seem totally unrelated to the
compiler. I don't know whether there is a simply solution to this
problem (or rather a nuisance).

Regards,
Stuart
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top