By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,406 Members | 888 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,406 IT Pros & Developers. It's quick & easy.

const functions problems...

P: n/a
How can I avoid writting and maintaining the same code in the two operator
[] implementation below? I know that in the minimal example below, the
implementation is trivial, but I found this type of problem (maintaining two
function overloads one const and one not const - having the same body), many
times...

Thanks,
Romulus
#include <iostream>

class SomeClass
{
public:
int & operator[](int index)
{
return array[index];
}

const int & operator[](int index) const
{
return array[index];
}

protected:
// internal data
int array[10];
};

void func(const SomeClass & sc, int index)
{
std::cout << sc[index] << std::endl;
}

void main(void)
{
SomeClass c;
c[3] = 5;
func(c, 3);
}
Jul 19 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a

"Romulus Mare" <mo****************@yahoo.com> wrote in message
news:bh************@ID-1317.news.uni-berlin.de...
How can I avoid writting and maintaining the same code in the two operator
[] implementation below? I know that in the minimal example below, the
implementation is trivial, but I found this type of problem (maintaining two function overloads one const and one not const - having the same body), many times...

Thanks,
Romulus


Sometimes an option is to use a const_cast, so the const version calls the
non-const version. This is legit provided the non-const version doesn't
modify the object during its execution (which is often the case).

class X
{
const int& func() const { return const_cast<X*>(this)->func(); }
int& func()
{
...
}
};

john
Jul 19 '05 #2

P: n/a
Sometimes an option is to use a const_cast, so the const version calls the
non-const version. This is legit provided the non-const version doesn't
modify the object during its execution (which is often the case).

class X
{
const int& func() const { return const_cast<X*>(this)->func(); }
int& func()
{
...
}
};


Thanks, John...

So, if I understood correctly, I am facing one of the following very
dangerous solutions:

1. Maintain the same code in two functions: one const and one not const
- OR -
2. Accept to work with the compiler not checking of constness in "non const"
int& func(). I know, the code is the same and should not do any
modifications in class, but this is no more elegant than old-style C cast...

Any other options for solving such issues?

Romulus
Jul 19 '05 #3

P: n/a
Romulus Mare wrote:
How can I avoid writting and maintaining the same code in the two
operator
[] implementation below? I know that in the minimal example below, the
implementation is trivial, but I found this type of problem
(maintaining two function overloads one const and one not const -
having the same body), many times...
I've seen people making use of const_cast for this (the only place I
know where it isn't a guaranteed sign for an error).
#include <iostream>

class SomeClass
{
public:
int & operator[](int index)
{
return array[index];
}

const int & operator[](int index) const
{
return array[index];
}
const int & operator[](int index) const
{
return const_cast<SomeClass*>(this)->operator[](index);
}

With this, you don't need to maintain two copies of the implementation.
Of course, you shouldn't modify the object in that implemention.
protected:
// internal data
int array[10];
};

void func(const SomeClass & sc, int index)
{
std::cout << sc[index] << std::endl;
}

void main(void)
main _must_ return int.
{
SomeClass c;
c[3] = 5;
func(c, 3);
}


Jul 19 '05 #4

P: n/a

"Romulus Mare" <mo****************@yahoo.com> wrote in message
news:bh************@ID-1317.news.uni-berlin.de...
Sometimes an option is to use a const_cast, so the const version calls the non-const version. This is legit provided the non-const version doesn't
modify the object during its execution (which is often the case).

class X
{
const int& func() const { return const_cast<X*>(this)->func(); }
int& func()
{
...
}
};

Thanks, John...

So, if I understood correctly, I am facing one of the following very
dangerous solutions:

1. Maintain the same code in two functions: one const and one not const
- OR -
2. Accept to work with the compiler not checking of constness in "non

const" int& func(). I know, the code is the same and should not do any
modifications in class, but this is no more elegant than old-style C cast...
Any other options for solving such issues?

Romulus


None that immediately spring to mind. Normally I find that such functions
are more or less one liners (as was your example), so the issue of
maintaining two identical functions doesn't really arise.

Perhaps if you could give some specific examples that you are concerned
about then someone might suggest some other possibilities.

john
Jul 19 '05 #5

P: n/a
On Mon, 11 Aug 2003 00:32:36 +0300,
Romulus Mare <mo****************@yahoo.com> wrote:
Sometimes an option is to use a const_cast, so the const version calls the
non-const version. This is legit provided the non-const version doesn't
modify the object during its execution (which is often the case).

class X
{
const int& func() const { return const_cast<X*>(this)->func(); }
int& func()
{
...
}
};


Thanks, John...

So, if I understood correctly, I am facing one of the following very
dangerous solutions:

1. Maintain the same code in two functions: one const and one not const
- OR -
2. Accept to work with the compiler not checking of constness in "non const"
int& func(). I know, the code is the same and should not do any
modifications in class, but this is no more elegant than old-style C cast...

Any other options for solving such issues?


Put the code in the const function, and const_cast to a const pointer and
call that function from the non-const function?

Add a third const function containing the implementation which is called
by both versions of func()?

--
Sam Holden

Jul 19 '05 #6

P: n/a
None that immediately spring to mind. Normally I find that such functions
are more or less one liners (as was your example), so the issue of
maintaining two identical functions doesn't really arise.
Well, unfortunately mine are not quite large but surely not one-liners.
Perhaps if you could give some specific examples that you are concerned
about then someone might suggest some other possibilities.
Cannot do it. The project and dependencies are quite large for a post in a
news group. This is why I tried to simplify the original posted code.
john

Jul 19 '05 #7

P: n/a
Put the code in the const function, and const_cast to a const pointer and
call that function from the non-const function?
How can I do this? const_case removes constness, is it not?
Add a third const function containing the implementation which is called
by both versions of func()?
Yes, but the problems remains the same. Working with const functions as not
const functions... Still old C style cast equivalent solution...
--
Sam Holden


Thanks.
Jul 19 '05 #8

P: n/a
On Mon, 11 Aug 2003 01:05:50 +0300,
Romulus Mare <mo****************@yahoo.com> wrote:
Put the code in the const function, and const_cast to a const pointer and
call that function from the non-const function?
How can I do this? const_case removes constness, is it not?


Possibly, I posted before I'd drunk my morning coffee, and the casting
part of C++ is something I am very unfamiliar with.

class A {
public:
int foo() const {return 10;}
int foo() {return const_cast<const A*>(this)->foo();}
};

compiles for me, but my compiler laughs at the standard and hence that
doesn't mean much.

If that isn't allowed (and someone will say so I'm sure :) then why not:

class A {
public:
int foo() const {return 10;}
int foo() {return static_cast<const A*>(this)->foo();}
};

[Note, I suspect I came in late on the thread, so sorry if I'm repeating
discounted solution, or misinterpreting the issue]
Add a third const function containing the implementation which is called
by both versions of func()?


Yes, but the problems remains the same. Working with const functions as not
const functions... Still old C style cast equivalent solution...


I don't understand that statement, but then again the morning coffee hasn't
kicked in yet (though it has now been consumed). The non-const function
would call the const helper function, that's fine and dandy :)

--
Sam Holden
Jul 19 '05 #9

P: n/a
"Romulus Mare" <mo****************@yahoo.com> wrote in message
news:bh************@ID-1317.news.uni-berlin.de...
How can I avoid writting and maintaining the same code in the two operator
[] implementation below? I know that in the minimal example below, the
implementation is trivial, but I found this type of problem (maintaining two function overloads one const and one not const - having the same body), many times...

Thanks,
Romulus
#include <iostream>

class SomeClass
{
public:
int & operator[](int index)
{
return array[index];
}

const int & operator[](int index) const
{
return array[index];
}

protected:
// internal data
int array[10];
};

void func(const SomeClass & sc, int index)
{
std::cout << sc[index] << std::endl;
}

void main(void)
{
SomeClass c;
c[3] = 5;
func(c, 3);
}


C++ has a keyword "mutable" which might be applicable to your situation --
I can't tell from the information revealed by your post. In principle it
avoids a const_cast in some situations, but now you have an implicit
const_cast every time you use it. I have never actually used "mutable"
myself.

BTW, I wouldn't agree that a const_cast is quite as bad as an old style C
cast. The C cast is more dangerous because it is more powerful. I think that
given that you want to cheat the system a little I think you will probably
have to own up to a const_cast someplace.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 19 '05 #10

P: n/a
Romulus Mare wrote:
Put the code in the const function, and const_cast to a const pointer
and call that function from the non-const function?


How can I do this? const_case removes constness, is it not?


Yes, but you could instead static_cast the this pointer into a const
pointer, and then const_cast the returned reference.
Add a third const function containing the implementation which is
called by both versions of func()?


Yes, but the problems remains the same. Working with const functions
as not const functions... Still old C style cast equivalent
solution...


Well, I'm afraid you have to live with the code duplication then.

Jul 19 '05 #11

P: n/a
On Mon, 11 Aug 2003 00:32:36 +0300, "Romulus Mare"
<mo****************@yahoo.com> wrote:
Sometimes an option is to use a const_cast, so the const version calls the
non-const version. This is legit provided the non-const version doesn't
modify the object during its execution (which is often the case).

class X
{
const int& func() const { return const_cast<X*>(this)->func(); }
int& func()
{
...
}
};

Thanks, John...

So, if I understood correctly, I am facing one of the following very
dangerous solutions:

1. Maintain the same code in two functions: one const and one not const
- OR -
2. Accept to work with the compiler not checking of constness in "non const"
int& func(). I know, the code is the same and should not do any
modifications in class, but this is no more elegant than old-style C cast...


Either you have to accept that the const version and non-const version
are different operations, and implement them separately, or you have
to accept that they are the same operation, and use the const cast.
You can't have it both ways...
Any other options for solving such issues?


A non-member template friend function might do the trick (one
instantiation for const T, one for non-const T), but that would be
crazy.

I suppose it would be nice to be able to template on cv-qualification
for template members. e.g.

class X
{
public:
template <cv qualifiers>
Y qualifiers& func() qualifiers;
};

//implement in cpp file.
//explicitly instantiate for no cv and for const.

However, I don't think it is useful enough to be worth adding to the
language, since it adds yet more headaches to argument deduction and
overloading.

Tom
Jul 19 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.