Topic: New overloadable operator: dynamic_cast
Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 10 Feb 2013 03:16:06 -0800 (PST)
Raw View
------=_Part_907_30025131.1360494966342
Content-Type: text/plain; charset=ISO-8859-1
I propose the ability for the user to overload the dynamic_cast operator.
There are two main use cases in the language right now:
Firstly, smart pointers. They can mimic the interface of raw pointers
almost exactly, but not in this regard. It also makes treating smart
pointers uniformly impossible, as each vendor has to introduce their own
pseudo-dynamic-cast.
Secondly, many existing systems, such as LLVM and ICU, currently implement
their own dynamic_cast, essentially, for their own types and classes. Being
able to overload dynamic_cast would enable a consistent interface for these
customised systems, as they can simply delegate the implementation.
Finally, unlike other operators, this would effectively involve overloading
the primitive operator on a primitive type (pointers) for some cases.
template<typename T> class shared_ptr {
...
template<typename U> shared_ptr<typename std::remove_pointer<U>::type>
operator dynamic_cast() {
return std::dynamic_pointer_cast<typename
std::remove_pointer<U>::type>(*this);
}
};
Here, the shared_ptr's operator is called when attempting to cast it, such
as
int main() {
std::shared_ptr<X> x;
auto y = dynamic_cast<Y*>(x);
}
Here, if anyone (probably just the implementation) wishes to have the
primitive semantics of dynamic_cast, they can simply take the address of x.
Also notice that unlike std::dynamic_pointer_cast, the template argument is
of the same form as the argument to the primitive operator.
class Value {
...
template<typename Other> Other operator dynamic_cast(llvmFunction* p) {
return llvm::dyn_cast<typename
std::remove_pointer<Other>::type>(this);
}
};
When the argument to dynamic_cast is a pointer, then the custom
dynamic_cast operator is invoked on pointers or references of this type,
hiding the primitive operator. In this case, it is assumed that the custom
functionality essentially replaces the primitive operator's implementation,
rather than extends its' interface as in shared_ptr. I don't propose a
means to retrieve the original operator's behaviour in this case.
int main() {
Value* p = ...;
auto constant = dynamic_cast<Constant*>(p); // Calls overloaded
operator.
}
I think that, given the prevalence of both user-defined pointer-imitating
types, and home-rolled RTTI replacements, it is worth a further extension
of flexibility as to how the language operates on pointers.
Feedback plix.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
------=_Part_907_30025131.1360494966342
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
I propose the ability for the user to overload the dynamic_cast operator. T=
here are two main use cases in the language right now:<div><br></div><div>F=
irstly, smart pointers. They can mimic the interface of raw pointers almost=
exactly, but not in this regard. It also makes treating smart pointers uni=
formly impossible, as each vendor has to introduce their own pseudo-dynamic=
-cast.</div><div>Secondly, many existing systems, such as LLVM and ICU, cur=
rently implement their own dynamic_cast, essentially, for their own types a=
nd classes. Being able to overload dynamic_cast would enable a consistent i=
nterface for these customised systems, as they can simply delegate the impl=
ementation.</div><div><br></div><div>Finally, unlike other operators, this =
would effectively involve overloading the primitive operator on a primitive=
type (pointers) for some cases.</div><div><br></div><div>template<typen=
ame T> class shared_ptr {</div><div> ...</div><div> &=
nbsp; template<typename U> shared_ptr<typename std::remove_pointer=
<U>::type> operator dynamic_cast() {</div><div>  =
; return std::dynamic_pointer_cast<typename std::remove_pointer&l=
t;U>::type>(*this);<br> }<br>};</div><div><br></div><div=
>Here, the shared_ptr's operator is called when attempting to cast it, such=
as</div><div><br></div><div>int main() {<br> std::shared_ptr&=
lt;X> x;</div><div> auto y =3D dynamic_cast<Y*>(x);</=
div><div>}</div><div><br></div><div>Here, if anyone (probably just the impl=
ementation) wishes to have the primitive semantics of dynamic_cast, they ca=
n simply take the address of x. Also notice that unlike std::dynamic_pointe=
r_cast, the template argument is of the same form as the argument to the pr=
imitive operator.</div><div><br></div><div>class Value {<br> .=
...</div><div> template<typename Other> Other operator dy=
namic_cast(llvmFunction* p) {</div><div> return =
llvm::dyn_cast<typename std::remove_pointer<Other>::type>(this)=
;<br> }<br>};</div><div><br></div><div>When the argument to dy=
namic_cast is a pointer, then the custom dynamic_cast operator is invoked o=
n pointers or references of this type, hiding the primitive operator. In th=
is case, it is assumed that the custom functionality essentially replaces t=
he primitive operator's implementation, rather than extends its' interface =
as in shared_ptr. I don't propose a means to retrieve the original operator=
's behaviour in this case.</div><div><br></div><div>int main() {<br> =
Value* p =3D ...;</div><div> auto constant =3D dynamic_=
cast<Constant*>(p); // Calls overloaded operator.</div><div>}</div><d=
iv><br></div><div>I think that, given the prevalence of both user-defined p=
ointer-imitating types, and home-rolled RTTI replacements, it is worth a fu=
rther extension of flexibility as to how the language operates on pointers.=
</div><div><br></div><div>Feedback plix.</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_907_30025131.1360494966342--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Feb 2013 15:50:55 +0200
Raw View
On 10 February 2013 13:16, DeadMG <wolfeinstein@gmail.com> wrote:
> I propose the ability for the user to overload the dynamic_cast operator.
> There are two main use cases in the language right now:
> Firstly, smart pointers. They can mimic the interface of raw pointers almost
> exactly, but not in this regard. It also makes treating smart pointers
> uniformly impossible, as each vendor has to introduce their own
> pseudo-dynamic-cast.
> Secondly, many existing systems, such as LLVM and ICU, currently implement
> their own dynamic_cast, essentially, for their own types and classes. Being
> able to overload dynamic_cast would enable a consistent interface for these
> customised systems, as they can simply delegate the implementation.
> Finally, unlike other operators, this would effectively involve overloading
> the primitive operator on a primitive type (pointers) for some cases.
> template<typename T> class shared_ptr {
> ...
> template<typename U> shared_ptr<typename std::remove_pointer<U>::type>
> operator dynamic_cast() {
> return std::dynamic_pointer_cast<typename
> std::remove_pointer<U>::type>(*this);
> }
> };
> Here, the shared_ptr's operator is called when attempting to cast it, such
> as
> int main() {
> std::shared_ptr<X> x;
> auto y = dynamic_cast<Y*>(x);
> }
> Here, if anyone (probably just the implementation) wishes to have the
> primitive semantics of dynamic_cast, they can simply take the address of x.
> Also notice that unlike std::dynamic_pointer_cast, the template argument is
> of the same form as the argument to the primitive operator.
> class Value {
> template<typename Other> Other operator dynamic_cast(llvmFunction* p) {
> return llvm::dyn_cast<typename
> std::remove_pointer<Other>::type>(this);
> }
> };
> When the argument to dynamic_cast is a pointer, then the custom dynamic_cast
> operator is invoked on pointers or references of this type, hiding the
> primitive operator. In this case, it is assumed that the custom
> functionality essentially replaces the primitive operator's implementation,
> rather than extends its' interface as in shared_ptr. I don't propose a means
> to retrieve the original operator's behaviour in this case.
>
> int main() {
> Value* p = ...;
> auto constant = dynamic_cast<Constant*>(p); // Calls overloaded
> operator.
> }
> I think that, given the prevalence of both user-defined pointer-imitating
> types, and home-rolled RTTI replacements, it is worth a further extension of
> flexibility as to how the language operates on pointers.
> Feedback plix.
I don't see a reason why this would be done with an overloadable
dynamic_cast operator
rather than with a generic dynamic_pointer_cast function that the
libraries can specialize.
The lookup of an overloaded operator for T in
dynamic_cast<whatever>(T*) looks seriously
odd, but that would be easily doable for the library solution. Then
again, in order to
allow for partial specializations, perhaps we need a trait rather than
a function template.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 10 Feb 2013 06:32:46 -0800 (PST)
Raw View
------=_Part_695_7313121.1360506766265
Content-Type: text/plain; charset=ISO-8859-1
Why do we use an overloaded operator<< rather than a free function? Or any
overloaded operator, for that matter.
Overloading an operator has the advantage that it can match existing
solutions which simply call dynamic_cast, and we don't end up with both a
language *and* library feature that perform the same function.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
------=_Part_695_7313121.1360506766265
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Why do we use an overloaded operator<< rather than a free function? O=
r any overloaded operator, for that matter.<div><br></div><div>Overloading =
an operator has the advantage that it can match existing solutions which si=
mply call dynamic_cast, and we don't end up with both a language *and* libr=
ary feature that perform the same function.</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_695_7313121.1360506766265--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Feb 2013 16:35:45 +0200
Raw View
On 10 February 2013 16:32, DeadMG <wolfeinstein@gmail.com> wrote:
> Why do we use an overloaded operator<< rather than a free function? Or any
> overloaded operator, for that matter.
For notational convenience. There is no such convenience difference
between dynamic_cast<T>
and dynamic_pointer_cast<T>.
> Overloading an operator has the advantage that it can match existing
> solutions which simply call dynamic_cast, and we don't end up with both a
> language *and* library feature that perform the same function.
Existing solutions don't exist - dynamic_cast doesn't currently work
for smart pointers
the way you want them to. And the language and the library feature
wouldn't perform
the same function - the library feature would be a superset of the
core functionality.
That seems just about right to me.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 10 Feb 2013 09:12:39 -0800 (PST)
Raw View
------=_Part_1185_5591163.1360516359145
Content-Type: text/plain; charset=ISO-8859-1
Except for the part where the primitive dynamic_cast now has absolutely
nothing going for it whatsoever. It's exactly the same as the library
version, except much less generic and flexible, and has many legacy calls
to it.
Existing solutions don't exist - dynamic_cast doesn't currently work for
> smart pointers the way you want them to.
That doesn't mean that there isn't existing code that isn't, say,
template<typename T> void f(T t) {
if (auto p = dynamic_cast<X*>(t)) {
//...
}
//...
}
Even a raw pointer specific version taking T* would still be upgraded for
use-cases with LLVM-style RTTI replacements without change, unlike your
library-based proposal.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
------=_Part_1185_5591163.1360516359145
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Except for the part where the primitive dynamic_cast now has absolutely not=
hing going for it whatsoever. It's exactly the same as the library version,=
except much less generic and flexible, and has many legacy calls to it.<di=
v><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px =
0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); borde=
r-left-style: solid; padding-left: 1ex;">Existing solutions don't exist - d=
ynamic_cast doesn't currently work for smart pointers the way you want=
them to.</blockquote><div><br></div><div>That doesn't mean that there isn'=
t existing code that isn't, say,</div><div><br></div><div>template<typen=
ame T> void f(T t) {<br> if (auto p =3D dynamic_cast<X*&=
gt;(t)) {<br> //...</div><div> }</d=
iv><div> //...</div><div>}</div><div><br></div><div>Even a raw=
pointer specific version taking T* would still be upgraded for use-cases w=
ith LLVM-style RTTI replacements without change, unlike your library-based =
proposal. </div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_1185_5591163.1360516359145--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 10 Feb 2013 11:34:42 -0800 (PST)
Raw View
------=_Part_253_24027882.1360524882344
Content-Type: text/plain; charset=ISO-8859-1
On Sunday, February 10, 2013 9:12:39 AM UTC-8, DeadMG wrote:
>
> Except for the part where the primitive dynamic_cast now has absolutely
> nothing going for it whatsoever. It's exactly the same as the library
> version, except much less generic and flexible, and has many legacy calls
> to it.
>
> Existing solutions don't exist - dynamic_cast doesn't currently work for
>> smart pointers the way you want them to.
>
>
> That doesn't mean that there isn't existing code that isn't, say,
>
> template<typename T> void f(T t) {
> if (auto p = dynamic_cast<X*>(t)) {
> //...
> }
> //...
> }
>
> Even a raw pointer specific version taking T* would still be upgraded for
> use-cases with LLVM-style RTTI replacements without change, unlike your
> library-based proposal.
>
And that last part is exactly why we *shouldn't* have this.
When I see `dynamic_cast` in code, I know that it means "use the language
feature". Therefore, I know that it will always work across all C++
implementations the same way. I should not expect `dynamic_cast` to invoke
some user-created casting system.
The fact that we need hacks like `std::addressof` to be sure we're getting
the address of an object in template code is enough of an eye-sore. What
kind of hack would you suggest for users who want to use the actual
language feature, rather than some user-defined code that requires macros
or some other nonsense?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
------=_Part_253_24027882.1360524882344
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Sunday, February 10, 2013 9:12:39 AM UTC-8, DeadMG wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;">Except for the part where the primitive dynam=
ic_cast now has absolutely nothing going for it whatsoever. It's exactly th=
e same as the library version, except much less generic and flexible, and h=
as many legacy calls to it.<div><br></div><blockquote class=3D"gmail_quote"=
style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:=
rgb(204,204,204);border-left-style:solid;padding-left:1ex">Existing solutio=
ns don't exist - dynamic_cast doesn't currently work for smart pointers&nbs=
p;the way you want them to.</blockquote><div><br></div><div>That doesn't me=
an that there isn't existing code that isn't, say,</div><div><br></div><div=
>template<typename T> void f(T t) {<br> if (auto p =3D d=
ynamic_cast<X*>(t)) {<br> //...</div><div>=
}</div><div> //...</div><div>}</div><div><br></d=
iv><div>Even a raw pointer specific version taking T* would still be upgrad=
ed for use-cases with LLVM-style RTTI replacements without change, unlike y=
our library-based proposal.</div></blockquote><div><br>And that last part i=
s exactly why we <i>shouldn't</i> have this.<br><br>When I see `dynamic_cas=
t` in code, I know that it means "use the language feature". Therefore, I k=
now that it will always work across all C++ implementations the same way. I=
should not expect `dynamic_cast` to invoke some user-created casting syste=
m.<br><br>The fact that we need hacks like `std::addressof` to be sure we'r=
e getting the address of an object in template code is enough of an eye-sor=
e. What kind of hack would you suggest for users who want to use the actual=
language feature, rather than some user-defined code that requires macros =
or some other nonsense? <br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_253_24027882.1360524882344--
.
Author: Jeffrey Yasskin <jyasskin@googlers.com>
Date: Sun, 10 Feb 2013 11:41:52 -0800
Raw View
I was thinking that we can already overload static_cast<T>(u) by
defining U::operator T(), and so it makes sense to be able to define
dynamic_cast in a parallel way. But then I remembered that C++11 also
defines static_pointer_cast and const_pointer_cast, so overloading
dynamic_cast to accomplish what dynamic_pointer_cast currently
accomplishes, would not in fact be parallel with static_cast. So +1 to
using dynamic_pointer_cast<> for this.
On Sun, Feb 10, 2013 at 3:16 AM, DeadMG <wolfeinstein@gmail.com> wrote:
> I propose the ability for the user to overload the dynamic_cast operator.
> There are two main use cases in the language right now:
>
> Firstly, smart pointers. They can mimic the interface of raw pointers almost
> exactly, but not in this regard. It also makes treating smart pointers
> uniformly impossible, as each vendor has to introduce their own
> pseudo-dynamic-cast.
> Secondly, many existing systems, such as LLVM and ICU, currently implement
> their own dynamic_cast, essentially, for their own types and classes. Being
> able to overload dynamic_cast would enable a consistent interface for these
> customised systems, as they can simply delegate the implementation.
>
> Finally, unlike other operators, this would effectively involve overloading
> the primitive operator on a primitive type (pointers) for some cases.
>
> template<typename T> class shared_ptr {
> ...
> template<typename U> shared_ptr<typename std::remove_pointer<U>::type>
> operator dynamic_cast() {
> return std::dynamic_pointer_cast<typename
> std::remove_pointer<U>::type>(*this);
> }
> };
>
> Here, the shared_ptr's operator is called when attempting to cast it, such
> as
>
> int main() {
> std::shared_ptr<X> x;
> auto y = dynamic_cast<Y*>(x);
> }
>
> Here, if anyone (probably just the implementation) wishes to have the
> primitive semantics of dynamic_cast, they can simply take the address of x.
> Also notice that unlike std::dynamic_pointer_cast, the template argument is
> of the same form as the argument to the primitive operator.
>
> class Value {
> ...
> template<typename Other> Other operator dynamic_cast(llvmFunction* p) {
> return llvm::dyn_cast<typename
> std::remove_pointer<Other>::type>(this);
> }
> };
>
> When the argument to dynamic_cast is a pointer, then the custom dynamic_cast
> operator is invoked on pointers or references of this type, hiding the
> primitive operator. In this case, it is assumed that the custom
> functionality essentially replaces the primitive operator's implementation,
> rather than extends its' interface as in shared_ptr. I don't propose a means
> to retrieve the original operator's behaviour in this case.
>
> int main() {
> Value* p = ...;
> auto constant = dynamic_cast<Constant*>(p); // Calls overloaded
> operator.
> }
>
> I think that, given the prevalence of both user-defined pointer-imitating
> types, and home-rolled RTTI replacements, it is worth a further extension of
> flexibility as to how the language operates on pointers.
>
> Feedback plix.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 10 Feb 2013 11:57:49 -0800 (PST)
Raw View
------=_Part_191_30307676.1360526269538
Content-Type: text/plain; charset=ISO-8859-1
It doesn't require macros or any other nonsense. The interface for
dynamic_cast is exactly the same.
The fact that we need hacks like `std::addressof` to be sure we're getting
> the address of an object in template code is enough of an eye-sore.
There's a very big difference- primarily that for all existing types where
dynamic_cast is legal, a dynamic_cast overload should act exactly the same.
It's only the* implementation* that people are looking to replace. The
whole point is to keep a *uniform* interface for all existing types, even
those with homegrown implementations, and extend the range of types where
it is legal. On the other hand, the entire purpose of overloading operator&
is to give a *different* interface.
There's no uniform interface in having to use std::dynamic_pointer_cast for
one pointer type, dynamic_cast for some others, and llvm::dyn_cast for yet
others.
But then I remembered that C++11 also defines static_pointer_cast and
> const_pointer_cast
The issue is that for primitive types, explicit conversions and explicit
casts aren't really the same thing. Strictly, for an existing pointer, you
can't do
Base* b = nullptr;
Derived* d(b);
but you can do
Base* b = nullptr;
Derived* d = static_cast<Derived*>(d);
So arguably, if you want all the casts to be treated equivalently, you
would have to add overloading for static_cast and const_cast. Adding
U::operator T() does not produce the same semantics, as you can't enable
static_casting but disable explicit conversion in other contexts. This is
another place where primitives have features that UDTs can never have,
which is wrong.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
------=_Part_191_30307676.1360526269538
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
It doesn't require macros or any other nonsense. The interface for dynamic_=
cast is exactly the same.<div><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-colo=
r: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">The fa=
ct that we need hacks like `std::addressof` to be sure we're getting the ad=
dress of an object in template code is enough of an eye-sore.</blockquote><=
div><br></div><div>There's a very big difference- primarily that for all ex=
isting types where dynamic_cast is legal, a dynamic_cast overload should ac=
t exactly the same. It's only the<i> implementation</i> that people are loo=
king to replace. The whole point is to keep a *uniform* interface for all e=
xisting types, even those with homegrown implementations, and extend the ra=
nge of types where it is legal. On the other hand, the entire purpose of ov=
erloading operator& is to give a *different* interface. </div><div=
><br></div><div>There's no uniform interface in having to use std::dynamic_=
pointer_cast for one pointer type, dynamic_cast for some others, and llvm::=
dyn_cast for yet others.</div><div><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left=
-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">&=
nbsp;But then I remembered that C++11 also defines static_pointer_cast=
and const_pointer_cast</blockquote><div><br></div><div>The issue is that f=
or primitive types, explicit conversions and explicit casts aren't really t=
he same thing. Strictly, for an existing pointer, you can't do</div><div><b=
r></div><div>Base* b =3D nullptr;</div><div>Derived* d(b);</div><div><br></=
div><div>but you can do</div><div><br></div><div>Base* b =3D nullptr;</div>=
<div>Derived* d =3D static_cast<Derived*>(d);</div><div><br></div><di=
v>So arguably, if you want all the casts to be treated equivalently, you wo=
uld have to add overloading for static_cast and const_cast. Adding U::opera=
tor T() does not produce the same semantics, as you can't enable static_cas=
ting but disable explicit conversion in other contexts. This is another pla=
ce where primitives have features that UDTs can never have, which is wrong.=
</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_191_30307676.1360526269538--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Sun, 10 Feb 2013 14:12:45 -0800
Raw View
On Sun, Feb 10, 2013 at 3:16 AM, DeadMG <wolfeinstein@gmail.com> wrote:
> I propose the ability for the user to overload the dynamic_cast operator.
> There are two main use cases in the language right now:
>
> Firstly, smart pointers. They can mimic the interface of raw pointers almost
> exactly, but not in this regard. It also makes treating smart pointers
> uniformly impossible, as each vendor has to introduce their own
> pseudo-dynamic-cast.
> Secondly, many existing systems, such as LLVM and ICU, currently implement
> their own dynamic_cast, essentially, for their own types and classes. Being
> able to overload dynamic_cast would enable a consistent interface for these
> customised systems, as they can simply delegate the implementation.
>
> Finally, unlike other operators, this would effectively involve overloading
> the primitive operator on a primitive type (pointers) for some cases.
>
> template<typename T> class shared_ptr {
> ...
> template<typename U> shared_ptr<typename std::remove_pointer<U>::type>
> operator dynamic_cast() {
> return std::dynamic_pointer_cast<typename
> std::remove_pointer<U>::type>(*this);
> }
> };
>
> Here, the shared_ptr's operator is called when attempting to cast it, such
> as
>
> int main() {
> std::shared_ptr<X> x;
> auto y = dynamic_cast<Y*>(x);
> }
>
> Here, if anyone (probably just the implementation) wishes to have the
> primitive semantics of dynamic_cast, they can simply take the address of x.
> Also notice that unlike std::dynamic_pointer_cast, the template argument is
> of the same form as the argument to the primitive operator.
>
> class Value {
> ...
> template<typename Other> Other operator dynamic_cast(llvmFunction* p) {
> return llvm::dyn_cast<typename
> std::remove_pointer<Other>::type>(this);
> }
> };
>
> When the argument to dynamic_cast is a pointer, then the custom dynamic_cast
> operator is invoked on pointers or references of this type, hiding the
> primitive operator. In this case, it is assumed that the custom
> functionality essentially replaces the primitive operator's implementation,
> rather than extends its' interface as in shared_ptr. I don't propose a means
> to retrieve the original operator's behaviour in this case.
>
> int main() {
> Value* p = ...;
> auto constant = dynamic_cast<Constant*>(p); // Calls overloaded
> operator.
> }
>
> I think that, given the prevalence of both user-defined pointer-imitating
> types, and home-rolled RTTI replacements, it is worth a further extension of
> flexibility as to how the language operates on pointers.
>
> Feedback plix.
Speaking as an LLVM developer, I don't think we would use this, even
if it became available in every compiler we care about. Using a
different name for our own dynamic cast operation is an advantage, not
a problem to be solved -- for instance, we can currently trivially
tell if a dynamic cast operation will be lightweight by how it is
spelled.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 10 Feb 2013 15:07:51 -0800 (PST)
Raw View
------=_Part_1315_4055920.1360537671295
Content-Type: text/plain; charset=ISO-8859-1
On Sunday, February 10, 2013 2:12:45 PM UTC-8, Richard Smith wrote:
>
> On Sun, Feb 10, 2013 at 3:16 AM, DeadMG <wolfei...@gmail.com <javascript:>>
> wrote:
> > I propose the ability for the user to overload the dynamic_cast
> operator.
> > There are two main use cases in the language right now:
> >
> > Firstly, smart pointers. They can mimic the interface of raw pointers
> almost
> > exactly, but not in this regard. It also makes treating smart pointers
> > uniformly impossible, as each vendor has to introduce their own
> > pseudo-dynamic-cast.
> > Secondly, many existing systems, such as LLVM and ICU, currently
> implement
> > their own dynamic_cast, essentially, for their own types and classes.
> Being
> > able to overload dynamic_cast would enable a consistent interface for
> these
> > customised systems, as they can simply delegate the implementation.
> >
> > Finally, unlike other operators, this would effectively involve
> overloading
> > the primitive operator on a primitive type (pointers) for some cases.
> >
> > template<typename T> class shared_ptr {
> > ...
> > template<typename U> shared_ptr<typename
> std::remove_pointer<U>::type>
> > operator dynamic_cast() {
> > return std::dynamic_pointer_cast<typename
> > std::remove_pointer<U>::type>(*this);
> > }
> > };
> >
> > Here, the shared_ptr's operator is called when attempting to cast it,
> such
> > as
> >
> > int main() {
> > std::shared_ptr<X> x;
> > auto y = dynamic_cast<Y*>(x);
> > }
> >
> > Here, if anyone (probably just the implementation) wishes to have the
> > primitive semantics of dynamic_cast, they can simply take the address of
> x.
> > Also notice that unlike std::dynamic_pointer_cast, the template argument
> is
> > of the same form as the argument to the primitive operator.
> >
> > class Value {
> > ...
> > template<typename Other> Other operator dynamic_cast(llvmFunction*
> p) {
> > return llvm::dyn_cast<typename
> > std::remove_pointer<Other>::type>(this);
> > }
> > };
> >
> > When the argument to dynamic_cast is a pointer, then the custom
> dynamic_cast
> > operator is invoked on pointers or references of this type, hiding the
> > primitive operator. In this case, it is assumed that the custom
> > functionality essentially replaces the primitive operator's
> implementation,
> > rather than extends its' interface as in shared_ptr. I don't propose a
> means
> > to retrieve the original operator's behaviour in this case.
> >
> > int main() {
> > Value* p = ...;
> > auto constant = dynamic_cast<Constant*>(p); // Calls overloaded
> > operator.
> > }
> >
> > I think that, given the prevalence of both user-defined
> pointer-imitating
> > types, and home-rolled RTTI replacements, it is worth a further
> extension of
> > flexibility as to how the language operates on pointers.
> >
> > Feedback plix.
>
> Speaking as an LLVM developer, I don't think we would use this, even
> if it became available in every compiler we care about. Using a
> different name for our own dynamic cast operation is an advantage, not
> a problem to be solved -- for instance, we can currently trivially
> tell if a dynamic cast operation will be lightweight by how it is
> spelled.
>
I've never used LLVM, so I'm wondering what makes dyn_cast more efficient
than dynamic_cast? Ignoring the issue of executable bloat, that is. Or is
it more runtime efficient than dynamic_cast at all? That is, if you
implemented dyn_cast in some way that's more efficient than dynamic_cast,
why can't the C++ compiler implement it the same way?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
------=_Part_1315_4055920.1360537671295
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><br>On Sunday, February 10, 2013 2:12:45 PM UTC-8, Richard Smith wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">On Sun, Feb 10, 2013 at 3:16 A=
M, DeadMG <<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"u67eCVV1cDYJ">wolfei...@gmail.com</a>> wrote:
<br>> I propose the ability for the user to overload the dynamic_cast op=
erator.
<br>> There are two main use cases in the language right now:
<br>>
<br>> Firstly, smart pointers. They can mimic the interface of raw point=
ers almost
<br>> exactly, but not in this regard. It also makes treating smart poin=
ters
<br>> uniformly impossible, as each vendor has to introduce their own
<br>> pseudo-dynamic-cast.
<br>> Secondly, many existing systems, such as LLVM and ICU, currently i=
mplement
<br>> their own dynamic_cast, essentially, for their own types and class=
es. Being
<br>> able to overload dynamic_cast would enable a consistent interface =
for these
<br>> customised systems, as they can simply delegate the implementation=
..
<br>>
<br>> Finally, unlike other operators, this would effectively involve ov=
erloading
<br>> the primitive operator on a primitive type (pointers) for some cas=
es.
<br>>
<br>> template<typename T> class shared_ptr {
<br>> ...
<br>> template<typename U> shared_ptr<typename st=
d::remove_pointer<U>::type>
<br>> operator dynamic_cast() {
<br>> return std::dynamic_pointer_cast<<w=
br>typename
<br>> std::remove_pointer<U>::type>(<wbr>*this);
<br>> }
<br>> };
<br>>
<br>> Here, the shared_ptr's operator is called when attempting to cast =
it, such
<br>> as
<br>>
<br>> int main() {
<br>> std::shared_ptr<X> x;
<br>> auto y =3D dynamic_cast<Y*>(x);
<br>> }
<br>>
<br>> Here, if anyone (probably just the implementation) wishes to have =
the
<br>> primitive semantics of dynamic_cast, they can simply take the addr=
ess of x.
<br>> Also notice that unlike std::dynamic_pointer_cast, the template ar=
gument is
<br>> of the same form as the argument to the primitive operator.
<br>>
<br>> class Value {
<br>> ...
<br>> template<typename Other> Other operator dynami=
c_cast(llvmFunction* p) {
<br>> return llvm::dyn_cast<typename
<br>> std::remove_pointer<Other>::<wbr>type>(this);
<br>> }
<br>> };
<br>>
<br>> When the argument to dynamic_cast is a pointer, then the custom dy=
namic_cast
<br>> operator is invoked on pointers or references of this type, hiding=
the
<br>> primitive operator. In this case, it is assumed that the custom
<br>> functionality essentially replaces the primitive operator's implem=
entation,
<br>> rather than extends its' interface as in shared_ptr. I don't propo=
se a means
<br>> to retrieve the original operator's behaviour in this case.
<br>>
<br>> int main() {
<br>> Value* p =3D ...;
<br>> auto constant =3D dynamic_cast<Constant*>(p); =
// Calls overloaded
<br>> operator.
<br>> }
<br>>
<br>> I think that, given the prevalence of both user-defined pointer-im=
itating
<br>> types, and home-rolled RTTI replacements, it is worth a further ex=
tension of
<br>> flexibility as to how the language operates on pointers.
<br>>
<br>> Feedback plix.
<br>
<br>Speaking as an LLVM developer, I don't think we would use this, even
<br>if it became available in every compiler we care about. Using a
<br>different name for our own dynamic cast operation is an advantage, not
<br>a problem to be solved -- for instance, we can currently trivially
<br>tell if a dynamic cast operation will be lightweight by how it is
<br>spelled.<br></blockquote><div><br>I've never used LLVM, so I'm wonderin=
g what makes dyn_cast more efficient than dynamic_cast? Ignoring the issue =
of executable bloat, that is. Or is it more runtime efficient than dynamic_=
cast at all? That is, if you implemented dyn_cast in some way that's more e=
fficient than dynamic_cast, why can't the C++ compiler implement it the sam=
e way?<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_1315_4055920.1360537671295--
.
Author: Chandler Carruth <chandlerc@googlers.com>
Date: Sun, 10 Feb 2013 15:51:10 -0800
Raw View
--00235429d16491e1a704d56777ac
Content-Type: text/plain; charset=ISO-8859-1
On Sun, Feb 10, 2013 at 3:07 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> I've never used LLVM, so I'm wondering what makes dyn_cast more efficient
> than dynamic_cast? Ignoring the issue of executable bloat, that is. Or is
> it more runtime efficient than dynamic_cast at all? That is, if you
> implemented dyn_cast in some way that's more efficient than dynamic_cast,
> why can't the C++ compiler implement it the same way?
>
We assume we know the total set of types involved in the type hierarchy and
encode them in an enum in the base class. This lets the implementation be
extremely efficient, often a single comparison against a constant. It works
for LLVM because we know the bounds of the type hierarchy, but it doesn't
work for the generic C++ case because it can't know that bound.
The problem with implementing this in a normal C++ dynamic_cast is that it
is hard to express the concept "class A can only ever be subclassed by B,
C, and D". Marking any particular leaf class as final doesn't really help
that much.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
--00235429d16491e1a704d56777ac
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sun, Feb 10, 2013 at 3:07 PM, Nicol Bolas <span dir=3D"=
ltr"><<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank" class=3D"=
cremed">jmckesson@gmail.com</a>></span> wrote:<br><div class=3D"gmail_ex=
tra"><div class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">I've never used LLVM, so I'm wonderi=
ng what makes dyn_cast more efficient than dynamic_cast? Ignoring the issue=
of executable bloat, that is. Or is it more runtime efficient than dynamic=
_cast at all? That is, if you implemented dyn_cast in some way that's m=
ore efficient than dynamic_cast, why can't the C++ compiler implement i=
t the same way?<br>
</blockquote><div><br></div><div style>We assume we know the total set of t=
ypes involved in the type hierarchy and encode them in an enum in the base =
class. This lets the implementation be extremely efficient, often a single =
comparison against a constant. It works for LLVM because we know the bounds=
of the type hierarchy, but it doesn't work for the generic C++ case be=
cause it can't know that bound.</div>
<div style><br></div><div style>The problem with implementing this in a nor=
mal C++ dynamic_cast is that it is hard to express the concept "class =
A can only ever be subclassed by B, C, and D". Marking any particular =
leaf class as final doesn't really help that much.</div>
</div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
--00235429d16491e1a704d56777ac--
.