 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Sylvain Pion Guest
|
Posted: Mon Apr 10, 2006 5:06 pm Post subject: Simplifying cost-correctness |
|
|
When one writes const-correct classes, usually a lot of code
has to be duplicated between the const and the non-const version
of the member functions.
I was wondering if there is some ongoing to work on attempting
to enhance the language to simplify this task (e.g. some way of
factorizing the code between the two versions in a compact
manner) ?
--
Sylvain
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Tomás Guest
|
Posted: Mon Apr 10, 2006 6:06 pm Post subject: Re: Simplifying cost-correctness |
|
|
Sylvain Pion posted:
| Quote: | When one writes const-correct classes, usually a lot of code
has to be duplicated between the const and the non-const version
of the member functions.
I was wondering if there is some ongoing to work on attempting
to enhance the language to simplify this task (e.g. some way of
factorizing the code between the two versions in a compact
manner) ?
|
Do any of you do something akin to the following:
class Monkey
{
const Monkey& Climb() const
{
//Very complicated function containing
//a thousand lines of code
return *this;
}
Monkey& Climb()
{
const Monkey& untouchable = *this;
return const_cast<Monkey&>( untouchable.Climb() );
}
};
Seems like a very legitimate use of "const_cast" to me.
-Tomás
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Mon Apr 10, 2006 6:06 pm Post subject: Re: Simplifying cost-correctness |
|
|
Sylvain Pion <Sylvain.Pion (AT) sophia (DOT) inria.fr> writes:
| Quote: | When one writes const-correct classes, usually a lot of code
has to be duplicated between the const and the non-const version
of the member functions.
I was wondering if there is some ongoing to work on attempting
to enhance the language to simplify this task (e.g. some way of
factorizing the code between the two versions in a compact
manner) ?
|
Not that I know of. I'd like to see cv qualification as a template
parameter:
template <class T, cvqual CV>
struct foo
{
int CV x; // for example
};
That could make these things much easier to handle cleanly.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Guest
|
Posted: Mon Apr 10, 2006 10:04 pm Post subject: Re: Simplifying cost-correctness |
|
|
Yes, I do this exact same thing.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Gene Bushuyev Guest
|
|
| Back to top |
|
 |
Bronek Kozicki Guest
|
Posted: Thu Apr 13, 2006 4:06 pm Post subject: Re: Simplifying cost-correctness |
|
|
David Abrahams wrote:
| Quote: | I was wondering if there is some ongoing to work on attempting
to enhance the language to simplify this task (e.g. some way of
factorizing the code between the two versions in a compact
manner) ?
Not that I know of. I'd like to see cv qualification as a template
parameter:
|
and I'd like to see const constructor that can be used only to create const
objects. That would allow 1. more flexibility in defining class interface; 2.
performance optimizations when creating const objects.
struct A
{
A(); // 1
A() const; // 2
};
class B
{
B(); // 3
public:
B() const; // 4
};
int main()
{
A a1; // 1 called
const A a2; // 2 called
B b1; // error, constructor 3 not accessible
const B b2; // 4 called
}
... but there was not such proposal, thus there's no chance having something
like this in C++0x . Oh, and while we are at this; with "rvalue-this" we could
extend semantics to have separate constructor for creation of temporary
variables and for creation of named variables (direct-initialization)
B.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Martin Vejnár Guest
|
Posted: Fri Apr 14, 2006 8:06 am Post subject: Re: Simplifying cost-correctness |
|
|
Tomás wrote:
| Quote: | Sylvain Pion posted:
When one writes const-correct classes, usually a lot of code
has to be duplicated between the const and the non-const version
of the member functions.
I was wondering if there is some ongoing to work on attempting
to enhance the language to simplify this task (e.g. some way of
factorizing the code between the two versions in a compact
manner) ?
Do any of you do something akin to the following:
class Monkey
{
const Monkey& Climb() const
{
//Very complicated function containing
//a thousand lines of code
return *this;
}
Monkey& Climb()
{
const Monkey& untouchable = *this;
return const_cast<Monkey&>( untouchable.Climb() );
}
};
Seems like a very legitimate use of "const_cast" to me.
|
Why don't you do it this way? It seems cleaner to me...
class Monkey
{
void Climb2() const
{
//Very complicated function containing
//a thousand lines of code
}
Monkey & Climb()
{
Climb2();
return *this;
}
const Monkey & Climb() const
{
Climb2();
return *this;
}
};
OP was talking about duplicating "a lot of code" in const-correct
classes. I don't think that two lines are that many. Surely not enough
to advocate a use of a cast.
Although the code you (Tomás) posted is correct _now_, after several
modifications by different people, the cast may not be valid anymore. By
using that explicit cast, you deliberately and unnecessarily give up
type checking and expose yourself to unexpected behaviors.
--
Martin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Ivan Kolev Guest
|
Posted: Fri Apr 14, 2006 8:06 am Post subject: Re: Simplifying cost-correctness |
|
|
kevin.hall (AT) motioneng (DOT) com wrote:
| Quote: | Yes, I do this exact same thing.
|
I found that the opposite is usually more convenient:
class Monkey
{
const Monkey& Climb() const
{
return const_cast<Monkey&>(*this).Climb();
}
Monkey& Climb()
{
//Very complicated function containing
//a thousand lines of code
return *this;
}
};
And I think this idiom is obligatory even for simple functions (and
even for the most performance-sensitive one-liners, which should be
inline anyway and an additional one-line call would surely be inlined
too), to avoid the possible modification of just one of the two methods
in the future.
| Quote: | Seems like a very legitimate use of "const_cast" to me.
|
Indeed, I hope so, too.
Regards,
Ivan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Tomás Guest
|
Posted: Fri Apr 14, 2006 4:06 pm Post subject: Re: Simplifying cost-correctness |
|
|
Martin Vejnár posted:
| Quote: | class Monkey
{
void Climb2() const
{
//Very complicated function containing
//a thousand lines of code
}
Monkey & Climb()
{
Climb2();
return *this;
}
const Monkey & Climb() const
{
Climb2();
return *this;
}
};
|
Good solution.
I simply hadn't thought of that at the time of posting. Once again, this
proves that there's many solutions to any particular problem, and that some
solutions are better than others. Best thing is just to sit down and think,
think, think...
-Tomás
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Bronek Kozicki Guest
|
Posted: Fri Apr 14, 2006 5:06 pm Post subject: Re: Simplifying cost-correctness |
|
|
Ivan Kolev wrote:
| Quote: | I found that the opposite is usually more convenient:
const Monkey& Climb() const
{
return const_cast<Monkey&>(*this).Climb();
}
|
this is wrong. See what happens here:
const Monkey doda;
// . . .
doda.Climb();
here you effectively cast-away constness of doda object, which is UB. You
could notice funny symptoms if doda had static lifetime - such const objects
may live in immutable regions of memory and any member variable modification
in body of non-const Climb would result in memory access violation.
B.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Ivan Kolev Guest
|
Posted: Sun Apr 16, 2006 5:06 am Post subject: Re: Simplifying cost-correctness |
|
|
"Tomás" wrote:
| Quote: | Martin Vejnár posted:
class Monkey
{
void Climb2() const
{
//Very complicated function containing
//a thousand lines of code
}
Monkey & Climb()
{
Climb2();
return *this;
}
const Monkey & Climb() const
{
Climb2();
return *this;
}
};
Good solution.
|
However, I don't see this working in the case when the two methods must
return a part of the object, which is not trivially retrieved:
class Monkey
{
Finger& getFinger( int i );
const Finger& getFinger( int i ) const;
}
Duplication or a const_cast seems inevitable to me. And I also can't
see the dangers of the const_cast which Martin Vejnár mentioned.
But I agree with Bronek Kozicki that it's better to write the common
implementation inside the const method - not exactly because of the
reasons he gave (if the two methods are actually exactly the same
method with two faces, then that method *cannot* modify any member
variable), but because by writing the implementation inside the const
method the compiler will point out if you modify a member variable by
mistake.
Regards,
Ivan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
Earl Purple Guest
|
Posted: Wed Apr 26, 2006 2:06 am Post subject: Re: Simplifying cost-correctness |
|
|
Ivan Kolev wrote:
| Quote: | class Monkey
{
Finger& getFinger( int i );
const Finger& getFinger( int i ) const;
}
Duplication or a const_cast seems inevitable to me. And I also can't
see the dangers of the const_cast which Martin Vejnár mentioned.
|
template < typename M, typename F >
F & getFinger( M& m )
{
// complex code
}
Finger& Monkey::getFinger( int i )
{
return getFinger< Monkey, Finger >( i);
}
const Finger & Monkey::getFinger( int i ) const
{
return getFinger< const Monkey, const Finger >( i );
}
Of course the getFinger template is a free-function and not a friend
plus you want to hide this implementation detail completely in the
header so it probably gets out of hand just to avoid a const_cast.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|