Topic: Standard library template<T> require T* operator&()
Author: "Andy Glew" <aglew@students.wisc.edu>
Date: 1999/09/21 Raw View
> 20.1.3 doesn't actually require such a member function;
True
> it simply requires that the expression &t (where t is type T) be well formed.
That is not my reading.
It seems to be to say that T t; &t must have type T*.
Unless "well formed" has a standard specific meaning that I
have not grokked yet, I could see the member function
smart_ptr<T> smart_ptee<T>::operator&() {
return smart_ptr<T>(this);
}
as being colloquially well-formed. Yet table 20 seems to disallow this.
> Seems to me people felt that taking the address of an object was a
> fundamental operation, and that it would create implementation
> difficulties if &t could not be depended upon.
Fair enough. It does not seem to be necessary for value-copying
containers.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Andy Glew <glew@cs.wisc.edu>
Date: 1999/09/19 Raw View
A reply received by email:
>The chances are,
>however, that somepace in the library a temporary T* is being declared
>and initialized with the result of & as applied to your type. If &
>applied to your type returned something other than a regular pointer, it
>would fail at compile time.
Yes, that is exactly what is happening.
Worse, in some situations it does not fail to compile, but does the wrong thing.
For example, I had a template value_wrapper<T>
that is basically supposed to emulate all actions of its
primitive type. E.g. value_wrapper<int> is supposed to
act like an int in nearly all circumstances, except
with some value added.
Among the things value_wrapper<T> emulated was
T* value_wrapper<T>::operator&()
i.e.
int* value_wrapper<int>::operator&()
This allows things like
value_wrapper<int4bytes> w;
read(fd,&w,4);
to work (although I am sympathetic to people who
say that this code should *not* work.)
This worked fine as long as sizeof(value_wrapper<T>) == sizeof(T).
But when value_wrapper<T> added fields, only the first sizeof
bytes got initialized, as an int; the other bytes were not.
It turns out that the copy constructor used in the STL was decidig which
constructor to use based on *&; i.e.
container<T>
malloc'ed sizeof(T) bytes
but then called the constructor of typeof(*&T)
or, if value_wrapper<W> has W* value_wrapper<W>::operator&(),
container< value_wrapper<W> >
malloc'ed sizeof( value_wrapper<W> ) bytes
but then called the constructor of W.
Which compiled (GCC 2.95.1), but certainly gave the wrong answer.
This only squeaked through the compiler because value_wrapper<W> had implicit
conversions to and from W. Delete those, and at least I got compiler errors.
----
Anyway, so far as I can see, you can't safely change the return type of
T* T::operator&()
Which means that you cannot prevent ordinary pointers from being created.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Andy Glew <glew@cs.wisc.edu>
Date: 1999/09/17 Raw View
I was somewhat disappointed to see that section 20.1.3,
"Copy Construction", of the C++ standard says
that CopyConstructible requires that the parameter
to a standard library template must have a member
T* T::operator&().
I was hoping that it would be possible to define types
that were only accessible through smart pointers,
i.e. for whom
smart_ptr<T> T::operator&()
was the only public way of taking the address.
And then using those types in standard containers.
Q0: why this & requirement?
Q1: are there any ways around this? I suppose that
only using containers of the smart_pointers would
work.
Q2: are there any lint tools that enforce this restriction?
(Yeah, sigh: I just spent a day debugging my way through
the STL to find this. Obviously GCC 2.95 doesn't enforce
or warn about this.)
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]