Topic: Explicit Functions?
Author: renjithmohan@hotmail.com (Renjith Mohan)
Date: Thu, 16 Sep 2004 15:09:30 GMT Raw View
llewelly.at@xmission.dot.com (llewelly) wrote in message news:<86656hsfwf.fsf@Zorthluthik.local.bar>...
> stephen.clamage@sun.com (Steve Clamage) writes:
>
> > Renjith Mohan wrote:
> >
> >> Thus for e.g. if
> >> explicit void Func(unsigned char uParam1, long lParam2)
> >> {
> >> }
> >> Then the overload resolution processor should only allow an exact
> >> match on its arguments, not allowing any standard or user defined
> >> conversions.
> >
> > I am always mystified by suggestions to limit how a function can be
> > called.
> >
> > A function has an interface and some defined semantics. As the owner
> > of the function, why do you want to restrict how the parameter values
> > are computed?
>
> Some people think that sqrt('A') is a bizzare and possibly erroneous
> operation. But these people don't actually want to prevent you
> from doing it entirely - they just want you to write out
> long-hand: sqrt(char('A')). So it isn't necessarily a significant
> restriction.
> >
> > For example, given
> > int foo(const base_class&);
> > why do you care if I call it with a derived class? Or with an
> > unrelated class that can be converted to base_class? Isn't it my
> > choice, assuming I understand the semantics of foo?
> [snip]
>
> This isn't solely about the semantics of foo. It's at least as much
> (if not more) about implicit conversions. And please note that
> while derived& -> base& is likely to be desirable, C++ has other
> implicit conversions which are less likely to desirable.
>
> I believe that implicit conversions, carefully chosen, can be a
> powerful and vital kind of polymorphism, but anyone who has
> written non-trivial C++ code knows they come with plenty of risk -
> and that some of C++'s built-in implicit conversions are
> downright dangerous. So I find it surprising that you are
> surprised that someone wants to limit implicit conversions.
>
> Finally, note that function templates require an exact match (at least
> for arguments whose types are deduced.)
I believe that most of the times the implicit conversions are a
convenience.But there may arise occassions where a program
generated(in this case the compiler) conversion is not suited for the
semantics of the function. Any human judgement is better than a
program's. For e.g what if it is dangerous to call a overriden
function but is safe to call its base version how can i call that
function inside my function without knowing that the parameter is a
converted one(into a derived). RTTI is the only way i suppose. However
even with template specialization i dont see a way out of this
dilemma, because a static data flow analysis cant determine whether
such a conversion has been done. Templates too
work at compile time. Are we not in a type safe world where we can
impose constraints on types when the need arises?.
>
> ---
> [ 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.jamesd.demon.co.uk/csc/faq.html ]
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: jtomic@student.math.hr (Hiroaki Ramone)
Date: Thu, 16 Sep 2004 15:13:38 GMT Raw View
stephen.clamage@sun.com (Steve Clamage) wrote in message
> I am always mystified by suggestions to limit how a function can be
> called.
>
> A function has an interface and some defined semantics. As the owner
> of the function, why do you want to restrict how the parameter values
> are computed?
>
> For example, given
> int foo(const base_class&);
> why do you care if I call it with a derived class? Or with an
> unrelated class that can be converted to base_class? Isn't it my
> choice, assuming I understand the semantics of foo?
But if you write function like this:
void swim_array(base_class* p, int n){
for (int i = 0; i < n; ++i)
p[i].swim();
}
then it's not guaranted that function works with array of derived
objects and maybe you want to protect your function parameters from
the implicit conversion.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: Mon, 13 Sep 2004 23:12:53 GMT Raw View
Renjith Mohan wrote:
> Thus for e.g. if
> explicit void Func(unsigned char uParam1, long lParam2)
> {
> }
> Then the overload resolution processor should only allow an exact
> match on its arguments, not allowing any standard or user defined
> conversions.
I am always mystified by suggestions to limit how a function can be
called.
A function has an interface and some defined semantics. As the owner
of the function, why do you want to restrict how the parameter values
are computed?
For example, given
int foo(const base_class&);
why do you care if I call it with a derived class? Or with an
unrelated class that can be converted to base_class? Isn't it my
choice, assuming I understand the semantics of foo?
---
Steve Clamage, stephen.clamage@sun.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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Tue, 14 Sep 2004 03:18:40 GMT Raw View
stephen.clamage@sun.com (Steve Clamage) writes:
> Renjith Mohan wrote:
>
>> Thus for e.g. if
>> explicit void Func(unsigned char uParam1, long lParam2)
>> {
>> }
>> Then the overload resolution processor should only allow an exact
>> match on its arguments, not allowing any standard or user defined
>> conversions.
>
> I am always mystified by suggestions to limit how a function can be
> called.
>
> A function has an interface and some defined semantics. As the owner
> of the function, why do you want to restrict how the parameter values
> are computed?
Some people think that sqrt('A') is a bizzare and possibly erroneous
operation. But these people don't actually want to prevent you
from doing it entirely - they just want you to write out
long-hand: sqrt(char('A')). So it isn't necessarily a significant
restriction.
>
> For example, given
> int foo(const base_class&);
> why do you care if I call it with a derived class? Or with an
> unrelated class that can be converted to base_class? Isn't it my
> choice, assuming I understand the semantics of foo?
[snip]
This isn't solely about the semantics of foo. It's at least as much
(if not more) about implicit conversions. And please note that
while derived& -> base& is likely to be desirable, C++ has other
implicit conversions which are less likely to desirable.
I believe that implicit conversions, carefully chosen, can be a
powerful and vital kind of polymorphism, but anyone who has
written non-trivial C++ code knows they come with plenty of risk -
and that some of C++'s built-in implicit conversions are
downright dangerous. So I find it surprising that you are
surprised that someone wants to limit implicit conversions.
Finally, note that function templates require an exact match (at least
for arguments whose types are deduced.)
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: renjithmohan@hotmail.com (Renjith Mohan)
Date: Sat, 11 Sep 2004 00:11:36 GMT Raw View
Respecting the current syntax and semantics of the explicit keyword ,
is it grossly improper to hope for an extension which allows for the
usage of the keyword to apply to functions both member and otherwise?.
Thus for e.g. if
explicit void Func(unsigned char uParam1, long lParam2)
{
}
Then the overload resolution processor should only allow an exact
match on its arguments, not allowing any standard or user defined
conversions. On whether promotions should be allowed or not I am not
so sure.
Anyway an explicit and a non explicit version should not be allowed as
this will introduce ambiguities in the call.
I am just wondering whether such an extension would enable the library
writers from eliminating implicit conversion problems the same type of
problems that the explicit ctor solved.
In one of the threads Scot Meyers did publish the idea about an
explicit copy ctor to eliminate the problem of slicing. Why not extend
it?.
A nice side effect about this is that it can remove the abhorrence of
most developers to write a user defined operator when a need arises,
as they are afraid that it may allow implicit conversions.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Sun, 12 Sep 2004 00:03:30 GMT Raw View
renjithmohan@hotmail.com (Renjith Mohan) wrote (abridged):
> Respecting the current syntax and semantics of the explicit keyword ,
> is it grossly improper to hope for an extension which allows for the
> usage of the keyword to apply to functions both member and otherwise?.
>
> explicit void Func(unsigned char uParam1, long lParam2)
> {
> }
> Then the overload resolution processor should only allow an exact
> match on its arguments, not allowing any standard or user defined
> conversions. On whether promotions should be allowed or not I am not
> so sure.
Interesting idea. I think you need to make the syntax per-argument
instead, eg:
void func( unsigned char uParam1, explicit long lParam2 ) {
}
meaning an exact match is required for lParam2 but not uParam1. This also
extends naturally to constructor arguments. Currently:
struct S {
explicit S( long param );
};
does not say anything about conversions of param. Eg:
S s(0); // OK, despite conversion.
is allowed. With:
struct S {
explicit S( explicit long param );
};
each "explicit" is doing something different and useful.
This might provide a safe way for non-const references to bind to
temporaries. Given:
long func( explicit long &arg ) {
return ++arg;
}
void test() {
int x = 0;
long y = 0;
func( x ); // Error - no implicit conversion.
func( y ); // OK
func( y+1 ); // ??
}
Currently the last line is an error because y+1 produces a temporary which
cannot bind to a non-const reference. I think it would be safe to bind
provided the reference is declared explicit. So "explicit" should be
allowed on plain variables, too:
explicit long &y = 0;
(which should extend the life of the temporary long).
-- Dave Harris, Nottingham, UK
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: jtomic@student.math.hr (Hiroaki Ramone)
Date: Sun, 12 Sep 2004 16:57:54 GMT Raw View
renjithmohan@hotmail.com (Renjith Mohan) wrote in message news:<cd7223bc.0409091656.483ea528@posting.google.com>...
> explicit void Func(unsigned char uParam1, long lParam2)
> {
> }
> Then the overload resolution processor should only allow an exact
> match on its arguments, not allowing any standard or user defined
> conversions. On whether promotions should be allowed or not I am not
> so sure.
I think this aproach fixes that problem:
template <class T1, class T2>
void Func(T1 t1, T2 t2);
template<>
void Func(unsigned char uParam1, long lParam2){
}
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: renjithmohan@hotmail.com (Renjith Mohan)
Date: Sun, 12 Sep 2004 20:16:37 GMT Raw View
brangdon@cix.co.uk (Dave Harris) wrote in message news:<memo.20040911104233.1740A@brangdon.m>...
> renjithmohan@hotmail.com (Renjith Mohan) wrote (abridged):
> > Respecting the current syntax and semantics of the explicit keyword ,
> > is it grossly improper to hope for an extension which allows for the
> > usage of the keyword to apply to functions both member and otherwise?.
> >
> > explicit void Func(unsigned char uParam1, long lParam2)
> > {
> > }
> > Then the overload resolution processor should only allow an exact
> > match on its arguments, not allowing any standard or user defined
> > conversions. On whether promotions should be allowed or not I am not
> > so sure.
>
> Interesting idea. I think you need to make the syntax per-argument
> instead, eg:
>
> void func( unsigned char uParam1, explicit long lParam2 ) {
> }
>
> meaning an exact match is required for lParam2 but not uParam1. This also
> extends naturally to constructor arguments. Currently:
But its a pain to repeat it for each argument if the whole function
needs to be explicit. Also since now you have removed the keyword from
the function name part it goes against the syntax of constructors,
which also is a function for all practical purposes except for the
return type. By the way you have not said anything about return
types.What if they need to be explicit as well?.
> struct S {
> explicit S( long param );
> };
>
> does not say anything about conversions of param. Eg:
> S s(0); // OK, despite conversion.
>
> is allowed. With:
>
> struct S {
> explicit S( explicit long param );
> };
>
> each "explicit" is doing something different and useful.
>
> This might provide a safe way for non-const references to bind to
> temporaries. Given:
>
> long func( explicit long &arg ) {
> return ++arg;
> }
>
> void test() {
> int x = 0;
> long y = 0;
> func( x ); // Error - no implicit conversion.
> func( y ); // OK
> func( y+1 ); // ??
> }
>
> Currently the last line is an error because y+1 produces a temporary which
> cannot bind to a non-const reference. I think it would be safe to bind
> provided the reference is declared explicit.
Why so? A temporary binding to a non constant reference is so much
against a developer intuition that it is bound to surprise most.I
think this is the primary reason why a temporary cannot be bound to a
non constant reference.
In your example above, would it be legal to call func like this
long func( explicit long &arg ) {
return ++arg;
}
func(10L); //call with a temporary bound (exact match)
what would be the expectation of the caller if this is allowed?.
The whole idea about explicit is to remove unwarranted "behind the
scenes" activity when it is dangerous.
So "explicit" should be
> allowed on plain variables, too:
>
> explicit long &y = 0;
>
> (which should extend the life of the temporary long).
>
> -- Dave Harris, Nottingham, UK
>
> ---
> [ 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.jamesd.demon.co.uk/csc/faq.html ]
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]