Welcome to the { mindfrost82.com } forums.

You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today!

If you have any problems with the registration process or your account login, please contact contact us.

Go Back   { mindfrost82.com } > Gadget Corner > Tech Newsgroups > Programming > C++

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 08-12-2008, 09:41 PM
francis_r
 
Posts: n/a
Const method returning a functor to non-const method

class Test
{
public:
typedef boost::function<void()> Action;

void action()
{
}

Action getAction() const
{
return boost::bind(&Test::action, this);
}
};

Above code does not compile on Visual Studio 2005 Express Edition
because getAction is a "const" method. Is this compliant with the
standard? This seems counterintuitive to me since the state of the
object is not changed by calling this method.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #2 (permalink)  
Old 08-13-2008, 07:27 PM
PeterAPIIT@gmail.com
 
Posts: n/a
Re: Const method returning a functor to non-const method

I don't understand your problem and requirement.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #3 (permalink)  
Old 08-13-2008, 07:58 PM
SG
 
Posts: n/a
Re: Const method returning a functor to non-const method

Hello Francis,

your code doesn't compile because the pointer 'this' is of type 'const
Test*' within your const member function 'Test::getAction()'. You're
trying to bind this const pointer as first parameter to the non-const
member function Test::action() which expects a non-const pointer Test*
as first parameter. Your compiler is certainly rejecting ill-formed
code in this regard because the standard doesn't allow implicit const
casts.

The solution is to make both member functions either const or non-
const. This makes their 'this' pointers of the same type and doesn't
require an ugly const_cast in Test::getAction().

Note, that if it did compile you'd be able to do something like this:
void do_something(const Test& x)
{ x.getAction()(); }
which might change the object even though a const reference has been
passed to the function. It works against the idea of constness.

Cheers,
SG

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #4 (permalink)  
Old 08-13-2008, 07:58 PM
Thomas Lehmann
 
Posts: n/a
Re: Const method returning a functor to non-const method

On 12 Aug., 22:41, francis_r <francis.ramme...@gmail.com> wrote:
> class Test
> {
> public:
> typedef boost::function<void()> Action;
>
> void action()
> {
> }
>
> Action getAction() const
> {
> return boost::bind(&Test::action, this);
> }
>
> };
>
> Above code does not compile on Visual Studio 2005 Express Edition
> because getAction is a "const" method. Is this compliant with the
> standard? This seems counterintuitive to me since the state of the
> object is not changed by calling this method.


I'm thinking the compiler is right. In a const method you are trying
to
provide a none const access to your method "action"! "action" is
allowed
to change the content...



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #5 (permalink)  
Old 08-13-2008, 07:58 PM
Ulrich Eckhardt
 
Posts: n/a
Re: Const method returning a functor to non-const method

francis_r wrote:
> class Test
> {
> public:
> typedef boost::function<void()> Action;
>
> void action()
> {
> }
>
> Action getAction() const
> {
> return boost::bind(&Test::action, this);
> }
> };
>
> Above code does not compile on Visual Studio 2005 Express Edition
> because getAction is a "const" method. Is this compliant with the
> standard?


Yes. The point is that 'this' is a pointer to a const Test, while bind would
need a pointer to a non-const Test. BTW, I guess you could have reduced the
example even further:

...
void getAction() const
{
boost::bind( &Test::action, this); // anonymous temporary
}
...

> This seems counterintuitive to me since the state of the
> object is not changed by calling this method.


By the same logic, you would also be able to return references to non-const
members from const memberfunctions, after all returning a reference doesn't
change them. No, if that would compile, it would be a hole in the
const-ness of the object, so it shouldn't.

Uli


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #6 (permalink)  
Old 08-14-2008, 11:36 PM
Pavel Minaev
 
Posts: n/a
Re: Const method returning a functor to non-const method

On Aug 13, 10:58 pm, Ulrich Eckhardt <dooms...@knuut.de> wrote:
> francis_r wrote:
> > class Test
> > {
> > public:
> > typedef boost::function<void()> Action;

>
> > void action()
> > {
> > }

>
> > Action getAction() const
> > {
> > return boost::bind(&Test::action, this);
> > }
> > };

>
> > Above code does not compile on Visual Studio 2005 Express Edition
> > because getAction is a "const" method. Is this compliant with the
> > standard?

>
> Yes. The point is that 'this' is a pointer to a const Test, while bind would
> need a pointer to a non-const Test. BTW, I guess you could have reduced the
> example even further:
>
> ...
> void getAction() const
> {
> boost::bind( &Test::action, this); // anonymous temporary
> }
> ...
>
> > This seems counterintuitive to me since the state of the
> > object is not changed by calling this method.

>
> By the same logic, you would also be able to return references to non-const
> members from const memberfunctions, after all returning a reference doesn't
> change them. No, if that would compile, it would be a hole in the
> const-ness of the object, so it shouldn't.


Interestingly enough, it does compile in VS2008 when using its own
std::tr1 implementation for function & bind, rather than Boost. Thanks
for clarifying why this is a problem - I've reported it to MS as a
bug:

https://connect.microsoft.com/Visual...dbackID=361784


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #7 (permalink)  
Old 08-21-2008, 02:28 PM
ta0kira@yahoo.com
 
Posts: n/a
Re: Const method returning a functor to non-const method

On Aug 12, 4:41 pm, francis_r <francis.ramme...@gmail.com> wrote:

> Above code does not compile on Visual Studio 2005 Express Edition
> because getAction is a "const" method. Is this compliant with the
> standard? This seems counterintuitive to me since the state of the
> object is not changed by calling this method.


In this case, there's absolutely nothing wrong with a 'const_cast',
but the compiler is correct in not implicitly converting 'this' to a
pointer to non-const.
Kevin P. Barry

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #8 (permalink)  
Old 08-21-2008, 10:02 PM
peter koch larsen
 
Posts: n/a
Re: Const method returning a functor to non-const method

On 21 Aug., 15:28, ta0k...@yahoo.com wrote:
> On Aug 12, 4:41 pm, francis_r <francis.ramme...@gmail.com> wrote:
>
> > Above code does not compile on Visual Studio 2005 Express Edition
> > because getAction is a "const" method. Is this compliant with the
> > standard? This seems counterintuitive to me since the state of the
> > object is not changed by calling this method.

>
> In this case, there's absolutely nothing wrong with a 'const_cast',
> but the compiler is correct in not implicitly converting 'this' to a
> pointer to non-const.
> Kevin P. Barry
>

In this case - as is usually the case - there is everything wrong with
a const_cast. We must presume that the caller wants to use the
function, and if he does so, our constant object will be changed -
possibly resulting in undefined behaviour.

/Peter

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #9 (permalink)  
Old 08-22-2008, 07:47 AM
ta0kira@yahoo.com
 
Posts: n/a
Re: Const method returning a functor to non-const method

On Aug 21, 5:02 pm, peter koch larsen <peter.koch.lar...@gmail.com>
wrote:

> In this case - as is usually the case - there is everything wrong with
> a const_cast. We must presume that the caller wants to use the
> function, and if he does so, our constant object will be changed -
> possibly resulting in undefined behaviour.


The function doesn't modify the instance with the 'const_cast', and
what happens after the function's return isn't the concern of that
function. Sure, if the object is unconditionally 'const' then that
would be undefined behavior, but otherwise the 'const'-ness of the
function isn't compromised. In this case it's the class' author's
responsibility to document that calling the 'getAction' function on a
'const'-defined instance causes undefined behavior. In fact, I can't
think of a *more* appropriate circumstance to use a 'const_cast',
though such a move requires minor documentation for proper usage, as
does nearly every other non-trivial interface.
Kevin P. Barry

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #10 (permalink)  
Old 08-22-2008, 02:00 PM
Nick Hounsome
 
Posts: n/a
Re: Const method returning a functor to non-const method

On 12 Aug, 21:41, francis_r <francis.ramme...@gmail.com> wrote:
> class Test
> {
> public:
> typedef boost::function<void()> Action;
>
> void action()
> {
> }
>
> Action getAction() const
> {
> return boost::bind(&Test::action, this);
> }
>
> };
>
> Above code does not compile on Visual Studio 2005 Express Edition
> because getAction is a "const" method. Is this compliant with the
> standard? This seems counterintuitive to me since the state of the
> object is not changed by calling this method.


If your reasoning were valid the following would also be allowed:

class Test
{
public:
typedef int& Action;

int action;

Action getAction() const
{
return action;
}

void ModifyConst() const
{
getAction() = 42;
}
};

You will see that getAction does not modify the state of the object
and yet this is clearly wrong for exactly the same reason that
your example is wrong.

The general principal for const-correctness is that given only a
pointer to a const object you should never be able to call a non-const
method or modify a non-mutable value without explicitly casting away
constness.

Clearly your example is not const-correct:
const Test* tp;
tp->getAction()(); // calling non-const method

You can no-more be "a bit" const-correct than you can be "a bit"
pregnant.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
Reply

  { mindfrost82.com } > Gadget Corner > Tech Newsgroups > Programming > C++


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are Off
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT. The time now is 04:59 PM.


Powered by vBulletin, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.1.0 ©2007, Crawlability, Inc.
© 1999-2008 mindfrost82.com v11.0


Sponsors:
Modded Xbox | Bad Credit Loan | Remortgages | Credit Card | Online Image Resizer



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114