472,956 Members | 2,733 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,956 software developers and data experts.

an "optional const"

hello;-)

i frequently need the following construction:

ReturnParam § Function() §
{
/...do something.../
someType var § = something;
/...do something.../
return something;
}

where § may be 'const' or nothing. So, if the function is called as a
member function of a constant object, it needs exactly the same code
as its non-const sister, but with some additional 'const' somewhere in
the fuction.

To reduce code-doubling, it would be very nice to have some "optional
const", eg. something that the compiler automatically removes if the
fn is called on an non-const object and translates to 'const' if the
object is constant.

As i cant think of any possibility that this would break existing
code, and furthermore think it should be easy to implement.

So i'd like to know if someone sees any reason to not propose an
"optional const", and - just by the way ;-) - where i could to it...
Sep 15 '08 #1
6 2348
..rhavin grobert wrote:
hello;-)

i frequently need the following construction:

ReturnParam § Function() §
A 'const' in the return type does not matter. The difference, however,
is sometimes like this:

ReturnType Function() const

vs

ReturnType& Function()

Therefore, it's not "const" versus "non-const" in the return value type,
it's a "temporary object" versus "reference" or

ReturnType const& Function() const

vs

ReturnType & Function()

, i.e. the 'const' in the return type is not where you show it.
{
/...do something.../
someType var § = something;
/...do something.../
return something;
}

where § may be 'const' or nothing. So, if the function is called as a
member function of a constant object, it needs exactly the same code
as its non-const sister, but with some additional 'const' somewhere in
the fuction.

To reduce code-doubling, it would be very nice to have some "optional
const", eg. something that the compiler automatically removes if the
fn is called on an non-const object and translates to 'const' if the
object is constant.

As i cant think of any possibility that this would break existing
code, and furthermore think it should be easy to implement.

So i'd like to know if someone sees any reason to not propose an
"optional const", and - just by the way ;-) - where i could to it...
AFAIK, folks who are sure that the 'do something' parts in those two
functions do not differ at all, simply write a const version and in the
non-const version do the const_cast in and out:

ReturnType const& Function() const
{
/* do something */
}

ReturnType& Function()
{
return const_cast<ReturnType&>(
const_cast<ThisClass const&>(*this).Function()
);
}

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 15 '08 #2
On 15 Sep., 16:42, Victor Bazarov <v.Abaza...@comAcast.netwrote:
.rhavin grobert wrote:
hello;-)
i frequently need the following construction:
ReturnParam § Function() §

A 'const' in the return type does not matter. *The difference, however,
is sometimes like this:

* * *ReturnType Function() const

vs

* * *ReturnType& Function()

Therefore, it's not "const" versus "non-const" in the return value type,
it's a "temporary object" versus "reference" or

* * *ReturnType const& Function() const

vs

* * *ReturnType & Function()

, i.e. the 'const' in the return type is not where you show it.
{
* /...do something.../
* someType var § = something;
* /...do something.../
* return something;
}
where § may be 'const' or nothing. So, if the function is called as a
member function of a constant object, it needs exactly the same code
as its non-const sister, but with some additional 'const' somewhere in
the fuction.
To reduce code-doubling, it would be very nice to have some "optional
const", eg. something that the compiler automatically removes if the
fn is called on an non-const object and translates to 'const' if the
object is constant.
As i cant think of any possibility that this would break existing
code, and furthermore think it should be easy to implement.
So i'd like to know if someone sees any reason to not propose an
"optional const", *and - just by the way ;-) - where i could to it...

AFAIK, folks who are sure that the 'do something' parts in those two
functions do not differ at all, simply write a const version and in the
non-const version do the const_cast in and out:

* * *ReturnType const& Function() const
* * *{
* * * * */* do something */
* * *}

* * *ReturnType& Function()
* * *{
* * * * *return const_cast<ReturnType&>(
* * * * * * *const_cast<ThisClass const&>(*this).Function()
* * * * * * *);
* * *}
true for trivial functions, i use this macro for this:

#ifndef INLINE_NC
#define INLINE_NC(ret,fnc,fnnc,cls)\
inline ret fnc {return const_cast<ret>(static_cast<const cls
&>(*this).fnnc);}
#endif

but in not-so trivial cases, i often have to double the code.
struct Something;

Something* GetSomething()
{
SomethingOther* pS = DoSomething();
if (TestSomething(pS)
{
/*.. do something ..*/
return SomethingOther->Something();
} else {
/*.. do something else ..*/
return NULL;
}
}

Something const* GetSomething() const
{
SomethingOther const* pS = DoSomething();
if (TestSomething(pS)
{
/*.. do something ..*/
return SomethingOther->Something();
} else {
/*.. do something else ..*/
return NULL;
}
}
Sep 15 '08 #3
On Sep 15, 3:52 pm, ".rhavin grobert" <cl...@yahoo.dewrote:
[...]
but in not-so trivial cases, i often have to double the code.

struct Something;

Something* GetSomething()
{
SomethingOther* pS = DoSomething();
[...]
}

Something const* GetSomething() const
{
SomethingOther const* pS = DoSomething();
[...]

While your algorithm stays the same for both the const and non-const
member function you operate on different types; hence you need a
template. I guess the problem is that DoSomething uses other member
function that are also overloaded on the constness of the object. The
solution is to make /this/ an explicit parameter of a static member
function template:

Something* GetSomething () {
return DoGetSomething
<Something, SomethingOther(*this);
}

const Something* GetSomething () const {
return DoGetSomething
<const Something, const SomethingOther(*this);
}

template <class S, class SO, class This>
static S* DoGetSomething (This& self) {
SO* p = self.DoSomething ();
if (self.TestSomething (p)) {
/*.. do something ..*/
return p->GetSomething();
} else {
/*.. do something else ..*/
return 0;
}
}

Regards,
Vidar Hasfjord
Sep 15 '08 #4
Victor Bazarov wrote:
.rhavin grobert wrote:
>hello;-)

i frequently need the following construction:

ReturnParam § Function() §

A 'const' in the return type does not matter. The difference, however,
is sometimes like this:

ReturnType Function() const

vs

ReturnType& Function()
I'd say it's

const ReturnType& Function() const

vs

ReturnType& Function()

i.e. reference to const versus reference to non-const...
ReturnType const& Function() const
{
/* do something */
}

ReturnType& Function()
{
return const_cast<ReturnType&>(
const_cast<ThisClass const&>(*this).Function()
);
}
.... and here, you write that, too.

Sep 15 '08 #5
On Sep 15, 6:40*pm, "Alf P. Steinbach" <al...@start.nowrote:
[...]
* Victor Bazarov:
AFAIK, folks who are sure that the 'do something' parts in those two
functions do not differ at all, simply write a const version and in the
non-const version do the const_cast in and out:

Effectively, yes, but regarding syntax they try to avoid 'const_cast'.
[...]
One general code reuse scheme goes like this:

* * private:
* * * * ReturnType& fooImpl() const ...

* * public:
* * * * ReturnType& foo() { return fooImpl(); }
* * * * ReturnType const& foo() const { return fooImpl(); }
While this is often an acceptable solution it is not general. If
fooImpl should need to call other member functions with overload
resolution based on the constness of the object, then this solution
wont work. See code below.

Also, if fooImpl needs to return a reference to a member, as often is
the case, you still need a const_cast inside the implementation; since
fooImpl is const while the return value is not. In that case this
solution is no better than the cast'n'forward idiom.

The fully general and safe solution is to forward to a template
function:

// Const and non-const getter overloads

#include <iostream>
using namespace std;

typedef int X;

class C {
X x_;

public:
C () {}

void foo () {cout << "non-const\n";}
void foo () const {cout << "const\n";}

X& get () {
foo ();
return x_;
}

#if 0 // duplicate algorithm
const X& get () const {
foo ();
return x_;
}
#else // dangerous cast'n'forward idiom
const X& get () const {
return const_cast <C*(this)->get ();
}
#endif

// safe template solution

#if 1 // C++98
X& get2 () {return do_get2 <X(*this);}
const X& get2 () const {return do_get2 <const X(*this);}

template <class R, class This>
static R& do_get2 (This& self) {
self.foo ();
return self.x_;
}
#else // C++0x
X& get2 () {return do_get2 (*this);}
const X& get2 () const {return do_get2 (*this);}

template <class This>
static auto do_get2 (This& self) -decltype (self.x_)& {
self.foo ();
return self.x_;
}
#endif
};
void test_getter_overload ()
{
cout << "Non-const object tests:\n";
C c;
c.get (); // Ok, prints "non-const".
c.get2 (); // Ok, prints "non-const".

cout << "Const object tests:\n";
const C cc;
cc.get (); // Ouch, prints "non-const".
cc.get2 (); // Ok, prints "const".
}

Regards,
Vidar Hasfjord

Sep 15 '08 #6
On Sep 15, 8:25*pm, "Alf P. Steinbach" <al...@start.nowrote:
* Vidar Hasfjord:
[...]
* // safe template solution
#if 1 // C++98
* X& get2 () {return do_get2 <X(*this);}
* const X& get2 () const {return do_get2 <const X(*this);}
* template <class R, class This>
* static R& do_get2 (This& self) {
* * self.foo ();
* * return self.x_;
* }
[...]
I'm too crossed-eyed to really read the code, but I think it's one of those yes,
not "the" but "also one". Credit to some Easter Bloc guy (Russian?). Uh,
I don't follow/know.
correction, I see some "const_cast" above, and no matter how the code works that
shouldn't be there if it's the old code, above is *not* the old Russian scheme.
You misinterpret the example; my code included the cast'n'forward
solution only for illustration.
Anyway, the reason why nobody do such things in practice, but only as academic
exercises, is that it's far too much code size overhead for no real gain.
That's generally true. But for the problem presented by the OP I think
the template solution is appropriate. His common code may very well
depend on overload resolution based on object constness. Only a
template can provide that; unless he duplicates the code.

Regards,
Vidar Hasfjord
Sep 16 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: bucher | last post by:
Hi, I want to push a const auto_ptr into a vector, but the compile reports errors. Below is the code. class Folder; class Result; class Results { public: int size(){return _Items.size();}
3
by: H. S. | last post by:
Hi, I am trying to compile these set of C++ files and trying out class inheritence and function pointers. Can anybody shed some light why my compiler is not compiling them and where I am going...
3
by: Alexander Farber | last post by:
Hi, does anyone have an idea, why do I get the following error (I have to use g++296 on RedHat Linux as compiler): In file included from r_dir.cpp:9: r_obey.h:262: declaration of `const...
5
by: (Pete Cresswell) | last post by:
I've dabbled in "Optional" over the last few days and think I'm coming down against using it. Seems to me like it makes the code harder to read and more complicated. Instead of using Optional,...
4
by: C. J. Clegg | last post by:
A month or so ago I read a discussion about putting const ints in header files, and how one shouldn't put things in header files that allocate memory, etc. because they will generate multiple...
2
by: Oenone | last post by:
In our applications, we use the special value of DateTime.MinValue to represent "null dates" throughout all our code. We recently ran into an issue where we wanted an optional date parameter for a...
9
by: Gary | last post by:
Hi all! I've taken some time on learning the difference between "pointers to const variables" and "const pointer variables". The question is: in the following code, can we change the contents of...
20
by: liujiaping | last post by:
I'm confused about the program below: int main(int argc, char* argv) { char str1 = "abc"; char str2 = "abc"; const char str3 = "abc"; const char str4 = "abc"; const char* str5 = "abc";
6
by: Queez | last post by:
I've had a good look around and no-one seems to have mentioned this, which leads me to believe that I may be missing something simple. Basically, is there a way I can do the following, and if so,...
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.