473,507 Members | 2,476 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 2389
..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
2486
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
2451
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
1827
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
9481
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
6043
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
11892
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
1269
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
3507
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
5798
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,...
0
7223
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7114
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7321
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7488
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
5045
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4702
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3179
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1544
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
762
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.