Re: Is this portable? [static pointer casts, char* arithmetic]
On 14 Apr., 22:15, "Alf P. Steinbach" <al...@start.no> wrote:
SG:
I should add that I expected such a conversion not to create a new
copy (of the "pointee")
You can have value semantics or reference semantics but not both.
Choose poison! :-)
I did. I'd like to think of it as "polymorphic value semantic". :)
But one approach that I've investigated is the smart pointer that takes
responsibility for object creation, not just destruction, that is, you pr=
ovide
the construction arguments to the smart pointer, which delegates. Conclus=
ion
that as of C++98 it's doable but somewhat awful -- lots of macro st=
uff. And
there's a notational problem regarding default and copy construction.
Yeah. This should be a piece of cake with C++0x features. I was
thinking of a little helper function template that magically
constructs T for you without copying it:
cow<string> blah = make_cow<string>("foobar");
void test_string()
{
cow<string> x = string("hello");
cow<string> y = x;
cout << "*x --> " << *x << endl;
cout << "*y --> " << *y << endl;
cout << "shared = " << (&*x == &*y) << endl;
x.wref() += "123"; // "wref" for write access ...
cout << "*x --> " << *x << endl;
cout << "*y --> " << *y << endl;
cout << "shared = " << (&*x == &*y) << endl;
}
which is supposed to output:
*x --> hello
*y --> hello
shared = 1
*x --> hello123
*y --> hello
shared = 0
Uhm, I like your approach, at least the idea. When I've done this[1] I've=
always
abstracted the machinery as a building block to be used internally by a c=
lass,
while you put it around, which is nicer. :-)
Heheh :) Thanks.
My main motivation has so far just
been to explore, though, and in particular having reference counting for =
an
array where the client code retains only a smart pointer to a part of it,=
such
as a pointer to a process argument (I believe example given in project [1=
]).
However, I didn't run into very much need for casting.
I did. It's because I wanted to much. :)
Even though it may not be 100% UB-free it works like intended on 32bit
linux with G++ 4.3.2.
Here's the source code (will probably expire after one month):
http://en.pastebin.ca/1392123
Without the polymorphism requirement this would be fairly easy to
achieve. But I also tried to make this code:
[...]
For this to work that cow class would need a templated constructor that
dynamically allocated a clone of the derived argument.
Yes, correct. Well, it's not cloned (as in clone function being
invoked) but simply copy-constructed.
[...]
where the first "~derived" message is due to the temporary in the copy-
initialization and the 2nd one comes from the copy of derived hidden
behind a type-agnostic abstract wrapper.
Yes, but what's the problem?
I can't work around this ugly char* pointer arithmetic. Maybe you
can. If you can my hat is off to you. I was thinking of alternatives
but haven't come up with working ones so far.
For example, if C++ provided a feature (magic library function) that
lets me adjust a void pointer so that the following two pieces are
equivalent:
1. A* pa = ...;
B* pb = pa; // A derives from B
2. void adjust(void *&, typeinfo const& from, typeinfo const&
to);
void adjust(void const*&, typeinfo const& from, typeinfo const&
to);
A* pa = ...;
void* pvoid = pa;
adjust(pvoid,typeid(A*),typeid(B*));
B* pb = static_cast<B*>(pvoid);
then I wouldn't need this char* arithmetic anymore. The difference
between (1) and (2) is that (2) can be used with typeinfo objects that
are only known at runtime. I could use (2) because I don't know
anymore that typeid(*paw) is a concrete_wrapper<A> but I could get the
void* and typeinfo object through the type-agnostic abstract wrapper
interface.
Cheers!
SG