 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
David Turner Guest
|
Posted: Fri Jan 30, 2004 6:04 pm Post subject: Is &* a good idea? |
|
|
Hi everyone
I recently had reason to implement a proxy class, and got to thinking. In
several places I have done something similar to this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct. I appreciate that having auto_ptr<Foo> automatically convertible
to a Foo* might lead us into trouble with the "assignment is move" semantic,
however, for non-copyable proxies, is automatic conversion really such a bad
thing?
On the pro side, it makes the code a little less ugly. On the con side, it
might cause one to forget that one is not actually using an object of type
Foo*...
Any thoughts?
Regards
David Turner
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Tutone Guest
|
Posted: Sat Jan 31, 2004 1:45 am Post subject: Re: Is &* a good idea? |
|
|
"David Turner" <david (AT) firepro (DOT) co.za> wrote:
| Quote: | Is &* a good idea?
|
Generally, no.
| Quote: | I recently had reason to implement a proxy class,
and got to thinking. In
several places I have done something similar to
this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
|
bar(object.get());
use the get() member function. That's what it's there
for.
Best regards,
Tom
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free web site building tool. Try it!
http://webhosting.yahoo.com/ps/sb/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ivan Vecerina Guest
|
Posted: Sat Jan 31, 2004 1:46 am Post subject: Re: Is &* a good idea? |
|
|
Hi,
"David Turner" <david (AT) firepro (DOT) co.za> wrote
| Quote: | I recently had reason to implement a proxy class, and got to thinking. In
several places I have done something similar to this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct. I appreciate that having auto_ptr<Foo> automatically
convertible
to a Foo* might lead us into trouble with the "assignment is move"
semantic,
however, for non-copyable proxies, is automatic conversion really such a
bad
thing?
It addition to having real dangers, implicit conversions can be confusing |
to ususpecting readers maintaining the code.
| Quote: | On the pro side, it makes the code a little less ugly. On the con side,
it
might cause one to forget that one is not actually using an object of type
Foo*...
Exactly. |
std::auto_ptr<> has a member function intended to do exactly what you want:
.get()
Everyone knows and understand what it means, and is able to grep for it.
Furthermore: what if the auto_ptr instance contains a null pointer?
&* would lead to undefined behavior -- never a good choice.
.get() will return a null pointer, which might be what you want...
So: bar( object.get() );
hth,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jonathan Turkanis Guest
|
Posted: Sat Jan 31, 2004 1:47 am Post subject: Re: Is &* a good idea? |
|
|
"David Turner" <david (AT) firepro (DOT) co.za> wrote
| Quote: | Hi everyone
I recently had reason to implement a proxy class, and got to
thinking. In
several places I have done something similar to this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct. <snip
|
Definitely. The problem is that operator->() is a unary operator, but
can't be called like a normal unary operator. The typical usage in
this case would be
bar(object.get());
(Also, you should write
auto_ptr<Foo> object(new Foo);
Implicit conversion doesn't work in the reverse direction, either.)
Jonathan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Philipp Bachmann Guest
|
Posted: Sat Jan 31, 2004 1:48 am Post subject: Re: Is &* a good idea? |
|
|
Hello David,
| Quote: | std::auto_ptr<Foo> object = new Foo();
bar(&*object);
|
You could also call "auto_ptr<>::get()":
bar(object.get());
| Quote: | where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct. I appreciate that having auto_ptr<Foo> automatically convertible
to a Foo* might lead us into trouble with the "assignment is move" semantic,
however, for non-copyable proxies, is automatic conversion really such a bad
thing?
|
Making potentially expensive or dangerous things explicit is a good design principle
of the standard library. Consider e.g. someone designs a factory method which
returns not a pointer, but an auto_ptr<>:
struct foo {
virtual ~foo(void);
virtual void a(void);
};
class bar : public foo {
[...]
public:
[...]
};
std::auto_ptr< foo > createBar(void) {
return new bar;
}
And consider, auto_ptr<> provided an automatic conversion to foo* and the user
thought, "createBar()" actually returns foo* and therefore added a call to "delete", then
the object created will be destructed a second time on leaving the block. With current
"auto_ptr<>", your code won't even compile, which is better than a crash.
| Quote: | On the pro side, it makes the code a little less ugly. On the con side, it
might cause one to forget that one is not actually using an object of type
Foo*...
|
"auto_ptr<>" is not the only application for "&*" - I often come across the need to write
"&*" with iterators.
The confusion the expression "&*" may cause is due to the fact, that in C you could just erase
it away, because "&" is just the inverse of "*" there. But with a language which allowes you to
overload "operator*(void)" the programmers have to get used to "&*" in my opinion.
Cheers,
Philipp.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bob Bell Guest
|
Posted: Sat Jan 31, 2004 1:55 am Post subject: Re: Is &* a good idea? |
|
|
"David Turner" <david (AT) firepro (DOT) co.za> wrote
| Quote: | Hi everyone
I recently had reason to implement a proxy class, and got to thinking. In
several places I have done something similar to this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct. I appreciate that having auto_ptr<Foo> automatically convertible
to a Foo* might lead us into trouble with the "assignment is move" semantic,
however, for non-copyable proxies, is automatic conversion really such a bad
thing?
On the pro side, it makes the code a little less ugly. On the con side, it
might cause one to forget that one is not actually using an object of type
Foo*...
Any thoughts?
|
bar(object.get()) reads better to me
Bob Bell
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Sean Kelly Guest
|
Posted: Sat Jan 31, 2004 10:43 am Post subject: Re: Is &* a good idea? |
|
|
"David Turner" <david (AT) firepro (DOT) co.za> wrote
| Quote: |
the pro side, it makes the code a little less ugly. On the con side, it
might cause one to forget that one is not actually using an object of type
Foo*...
Any thoughts?
|
template<typename Ty>
inline Ty* get_ptr( Ty* val )
{
return val;
}
template<typename Ty>
inline Ty const* get_ptr( std::auto_ptr<Ty> const& val )
{
return val.get();
}
Problem solved It's semantically meaningful without requiring
changes to auto_ptr.
Sean
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Anderson Guest
|
Posted: Sat Jan 31, 2004 10:45 am Post subject: Re: Is &* a good idea? |
|
|
"David Turner" <david (AT) firepro (DOT) co.za> wrote
| Quote: | Hi everyone
I recently had reason to implement a proxy class, and got to thinking. In
several places I have done something similar to this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct. I appreciate that having auto_ptr<Foo> automatically
convertible |
then do not use it, do:
bar(object.get());
that's what I do
Danderson
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dave Harris Guest
|
Posted: Sat Jan 31, 2004 6:25 pm Post subject: Re: Is &* a good idea? |
|
|
[email]david (AT) firepro (DOT) co.za[/email] (David Turner) wrote (abridged):
| Quote: | I recently had reason to implement a proxy class, and got to
thinking. In several places I have done something similar to this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct.
|
With auto_ptr<> you can use get(). I find it more of an issue with
iterators. For example:
void use( int *p );
void demo( vector<int>::iterator vi, list<int>::iterator li ) {
use( &*vi );
use( &*li );
}
It's not uncommon to have functions like use() which take a pointer
so as to be neutral about where their data comes from (and please
don't tell me to make use() a template). If the data actually comes
from a standard container, I often have to convert an iterator into
a pointer. &* is the best way I know to do it.
-- Dave Harris, Nottingham, UK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Peter Dimov Guest
|
Posted: Sun Feb 01, 2004 3:26 pm Post subject: Re: Is &* a good idea? |
|
|
[email]brangdon (AT) cix (DOT) co.uk[/email] (Dave Harris) wrote in message news:<memo.20040131112238.932D (AT) brangdon (DOT) m>...
| Quote: | david (AT) firepro (DOT) co.za (David Turner) wrote (abridged):
I recently had reason to implement a proxy class, and got to
thinking. In several places I have done something similar to this:
std::auto_ptr<Foo> object = new Foo();
bar(&*object);
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct.
With auto_ptr<> you can use get(). I find it more of an issue with
iterators. For example:
void use( int *p );
void demo( vector<int>::iterator vi, list<int>::iterator li ) {
use( &*vi );
use( &*li );
}
It's not uncommon to have functions like use() which take a pointer
so as to be neutral about where their data comes from (and please
don't tell me to make use() a template).
|
The plain &*vi is usually incorrect. You either have
void use( int & r );
and pass it *vi, or you have
void use( int * p );
and pass it vi == v.end()? 0: &*vi.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ta0kira Guest
|
Posted: Sun Feb 01, 2004 8:09 pm Post subject: Re: Is &* a good idea? |
|
|
"David Turner" <david (AT) firepro (DOT) co.za> wrote
| Quote: | where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct.
|
The only reason I can think of to use &* is in a function that you will change
a pointer as well as return a value:
size_t HalfArray(double &*aArray, size_t sSize)
{
aArray = new double[sSize / 2];
return sSize / 2;
}
As far as a conversion operator, you would have to make its return type &* for
it to return &*, which I think would be a pretty bad idea, but if it is a
conversion operator to just * then I think that is pretty safe. If you used
a class with a conversion operator to * in a function that took &* I think it
just creates a temp copy anyway. Not sure if all this is what you were
talking about...
ta0kira
(Maybe using '&*const' would be safer???)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dave Harris Guest
|
Posted: Mon Feb 02, 2004 5:49 pm Post subject: Re: Is &* a good idea? |
|
|
[email]pdimov (AT) mmltd (DOT) net[/email] (Peter Dimov) wrote (abridged):
| Quote: | The plain &*vi is usually incorrect. You either have
void use( int & r );
and pass it *vi,
|
You're assuming a house style about the use of references here. In
some shops pointers are used even if they are not allowed to be NULL.
| Quote: | or you have
void use( int * p );
and pass it vi == v.end()? 0: &*vi.
|
If you know the iterator is valid there's no need to test against
v.end(), and indeed such a test may not be possible at the point
of call. It wasn't in my example. (This is true even if use() does
accept null pointers.)
-- Dave Harris, Nottingham, UK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ta0kira Guest
|
Posted: Tue Feb 10, 2004 8:07 pm Post subject: Re: Is &* a good idea? |
|
|
| Quote: | With auto_ptr<> you can use get(). I find it more of an issue with
iterators. For example:
void use( int *p );
void demo( vector<int>::iterator vi, list<int>::iterator li ) {
use( &*vi );
use( &*li );
}
|
That makes a lot of sense, with the exception of the fact that the return type
of 'operator *' is not required to be a reference: it only has to be of type
'std::iterator_traits <Iterator> ::reference' which in this case works out fine,
but do not forget that a 'std::vector <bool> ::reference' is actually a
'std::_Bit_reference'. This means that you can only use '&*' with an iterator
if you know for sure that the 'operator *' return type is an actual reference.
Although I understand using a * instead of a reference, it might be better to do
this (to allow for ALL iterator types):
void demo( vector<int>::iterator vi, list<int>::iterator li ) {
int Temp = *vi;
use( &Temp );
*vi = Temp;
Temp = *li;
use( &Temp );
*li = Temp;
}
That makes for 4 additional copy operations (in the case that the assignment
operator and copy constructor actually COPY), but it makes it more compatible
with varying iterator types. After all, the purpose of an iterator is so that
you don't have to have pointers and references as your public interface. Who
knows, maybe the data manipulated by an iterator is not internally represented
as a 'referenceable object' (i.e. it doesn't literally contain a pointer to
an object of the expected type, such as 'std::vector <bool> ::iterator'; hence
'::reference' being 'std::_Bit_reference' and not 'bool&'...)
ta0kira
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Fri Feb 13, 2004 1:52 am Post subject: Re: Is &* a good idea? |
|
|
In article <b5c14083.0402100059.2b8cc8d (AT) posting (DOT) google.com>, ta0kira wrote:
| Quote: | With auto_ptr<> you can use get(). I find it more of an issue with
iterators. For example:
void use( int *p );
void demo( vector<int>::iterator vi, list<int>::iterator li ) {
use( &*vi );
use( &*li );
}
That makes a lot of sense, with the exception of the fact that the return type
of 'operator *' is not required to be a reference: it only has to be of type
'std::iterator_traits <Iterator> ::reference'
|
Table 65 says the "reference" member of a container class has type
"lvalue of T" and the way to represent lvalue-ness in the type system
is to use reference types.
| Quote: | which in this case works out fine,
but do not forget that a 'std::vector <bool> ::reference' is actually a
'std::_Bit_reference'.
snip |
Which means vector<bool> is not a container:
<http://std.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#96>.
--
Ben Hutchings
Humour is the best antidote to reality.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Fri Feb 13, 2004 1:53 am Post subject: Re: Is &* a good idea? |
|
|
ta0kira wrote:
| Quote: | "David Turner" <david (AT) firepro (DOT) co.za> wrote in message
news:<1075463184.630072 (AT) tanzanite (DOT) firepro.co.za>...
where bar() takes a Foo*. It strikes me that &* is a very unnatural
construct.
The only reason I can think of to use &* is in a function that you
will change a pointer as well as return a value:
size_t HalfArray(double &*aArray, size_t sSize)
snip |
T&* appears to be a pointer to a reference to T, but "[t]here shall be
no...pointers to references." (8.3.2/4)
You're talking about references to pointers, written as T*&.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| 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
|
|