Topic: Using override & final to support virtual
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Mon, 9 Nov 2015 10:24:07 -0600
Raw View
--001a114844ec1b02e305241e081d
Content-Type: text/plain; charset=UTF-8
On 9 November 2015 at 10:09, <john.croix@gmail.com> wrote:
> struct Base
> {
> virtual void func(int &x);
> virtual void func(double &x);
> };
>
> struct Derived : public Base
> {
> template<typename T> void func(T &x) final;
> };
>
>
> Upon verification, the appropriate method can be generated from the
> template for Derived::func(int&) and/or Derived::func(double&), depending
> on which method(s) was invoked.
>
I'm not sure what you mean by invoked; you usually have to generate code
for all the virtual functions unless you can determine that they are never
called, including through a base class pointer or reference.
> Am I missing something? It seems like all of the pieces exist for the
> compiler to be able to handle this type of extension.
>
What is the motivating use case for such a feature?
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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/.
--001a114844ec1b02e305241e081d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 9 November 2015 at 10:09, <span dir=3D"ltr"><<a hre=
f=3D"mailto:john.croix@gmail.com" target=3D"_blank">john.croix@gmail.com</a=
>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote=
"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote style=3D"marg=
in:0 0 0 40px;border:none;padding:0px"><div>struct Base</div><div>{</div><d=
iv>=C2=A0 =C2=A0virtual void func(int &x);</div><div>=C2=A0 =C2=A0virtu=
al void func(double &x);</div><div>};</div><div><br></div><div>struct D=
erived : public Base</div><div>{</div><div>=C2=A0 =C2=A0template<typenam=
e T> void func(T &x) final;</div><div>};</div></blockquote><div>=C2=
=A0<div>Upon verification, the appropriate method can be generated from the=
template for Derived::func(int&) and/or Derived::func(double&), de=
pending on which method(s) was invoked. </div></div></div></blockquote><div=
><br></div><div>I'm not sure what you mean by invoked; you usually have=
to generate code for all the virtual functions unless you can determine th=
at they are never called, including through a base class pointer or referen=
ce.</div><div>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div><div>Am I missing something? It seems like all of the pieces exist =
for the compiler to be able to handle this type of extension.<br></div></di=
v></div></blockquote><div><br></div><div>What is the motivating use case fo=
r such a feature?</div></div>-- <br><div class=3D"gmail_signature">=C2=A0Ne=
vin ":-)" Liber=C2=A0 <mailto:<a href=3D"mailto:nevin@evilover=
lord.com" target=3D"_blank">nevin@eviloverlord.com</a>>=C2=A0 (847) 691-=
1404</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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a114844ec1b02e305241e081d--
.
Author: john.croix@gmail.com
Date: Mon, 9 Nov 2015 09:40:13 -0800 (PST)
Raw View
------=_Part_96_1682389510.1447090813309
Content-Type: multipart/alternative;
boundary="----=_Part_97_2066318760.1447090813309"
------=_Part_97_2066318760.1447090813309
Content-Type: text/plain; charset=UTF-8
On Monday, November 9, 2015 at 10:24:52 AM UTC-6, Nevin ":-)" Liber wrote:
>
> On 9 November 2015 at 10:09, <john....@gmail.com <javascript:>> wrote:
>
>> struct Base
>> {
>> virtual void func(int &x);
>> virtual void func(double &x);
>> };
>>
>> struct Derived : public Base
>> {
>> template<typename T> void func(T &x) final;
>> };
>>
>>
>> Upon verification, the appropriate method can be generated from the
>> template for Derived::func(int&) and/or Derived::func(double&), depending
>> on which method(s) was invoked.
>>
>
> I'm not sure what you mean by invoked; you usually have to generate code
> for all the virtual functions unless you can determine that they are never
> called, including through a base class pointer or reference.
>
Sorry - my bad for using imprecise terminology. You're right that, in
general, all versions would have to be created by the compiler unless it
can determine that a method is never called. I was thinking too far ahead
towards optimizations in which you might be able to determine that a
specific version(s) isn't called once you know what the entire program
looks like. If you were creating a library, for example, you wouldn't be
able to apply such optimizations, and every instance of the derived virtual
method would need to be created. Not creating a specific method would be
the exception, not the rule. Let's just forget that I said anything about
this for now.
>
>
>> Am I missing something? It seems like all of the pieces exist for the
>> compiler to be able to handle this type of extension.
>>
>
> What is the motivating use case for such a feature?
>
In my particular situation, I had a base class which supported a limited
number of parameter checks on different types. Because C++ doesn't support
virtual template methods, I had to explicitly enumerate each check. I
understand that, and my idea doesn't address that restriction.
class Base
{
...
public:
...
virtual bool validateParameter(const int &) const=0;
virtual bool validateParameter(const double &) const=0;
virtual bool validateParameter(const float &) const=0;
...
};
The checks in the derived classes were all the same, except for the type.
Each derived type, however, had a different check. Thus, I had to write
each of the interfaces for all inheriting classes, and from within each,
invoke the template that actually did the check.
class Derived1 : public Base
{
...
private:
...
template<typename T> bool validateParameterImpl(const T &t) const { ...
};
...
public:
...
bool validateParameter(const int &i) const final { return
validateParameterImpl( i ); }
bool validateParameter(const double &d) const final { return
validateParameterImpl( d ); }
bool validateParameter(const float &f) const final { return
validateParameterImpl( f ); }
...
};
class Derived2 : public Base
{
...
private:
...
template<typename T> bool validateParameterImpl(const T &t) const { ...
};
...
public:
...
bool validateParameter(const int &i) const final { return
validateParameterImpl( i ); }
bool validateParameter(const double &d) const final { return
validateParameterImpl( d ); }
bool validateParameter(const float &f) const final { return
validateParameterImpl( f ); }
...
};
If there's ever a need to go back to add a new type to the base class, I'll
have to go to each derived class and add a new method to it that just
invokes the underlying template implementation. All of the information is
there for the compiler, so it seems to me that it would be easier for the
programmer, and less error prone, to have the compiler do this type of
thing automatically:
class Derived1 : public Base
{
...
public:
...
template<typename T> bool validateParameter(const T &t) const final {
.... }
...
};
The compiler can generate versions of Derived1::validateParameter() for
int, double, and float. If I ever added "char" to Base, for example, the
compiler would take care of creating that method automatically instead of
me having to edit each source file to add a new method to each of the
derived classes.
The situation is obviously even more complex if there are multiple levels
of hierarchy involved that need to be modified. And if different people
wrote the different classes, coordination can be a nightmare. Having a
template class could significantly reduce ongoing support and reduce the
potential for introducing an error as new methods are introduced to the
base class.
I work in EDA (electronic design automation), and our software is
constantly updated as new rules are created for new IC process nodes. We're
in a continuous cycle of code additions as fabs roll out new methodologies,
which happens frequently. Anything that can help get away from the
copy/paste paradigm that junior programers tend to favor can go a long way
towards improving code stability and reducing development time. It's not a
matter of being lazy. If the compiler can do it for us, it would be better
to let the compiler do it than to have multiple people go in and out of the
code to make these types of changes.
--
> Nevin ":-)" Liber <mailto:ne...@eviloverlord.com <javascript:>> (847)
> 691-1404
>
--
---
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/.
------=_Part_97_2066318760.1447090813309
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Monday, November 9, 2015 at 10:24:52 AM UTC-6, Nevin ":-)&q=
uot; Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">On 9 November 2015 at 10:09, <span dir=3D"ltr"><<a href=3D"javascri=
pt:" target=3D"_blank" gdf-obfuscated-mailto=3D"QkUP5yWaFgAJ" rel=3D"nofoll=
ow" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;">john....@gmail.com</a>&=
gt;</span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><blockquote style=3D"margin:0 0 0 40px;border:non=
e;padding:0px"><div>struct Base</div><div>{</div><div>=C2=A0 =C2=A0virtual =
void func(int &x);</div><div>=C2=A0 =C2=A0virtual void func(double &=
;x);</div><div>};</div><div><br></div><div>struct Derived : public Base</di=
v><div>{</div><div>=C2=A0 =C2=A0template<typename T> void func(T &=
;x) final;</div><div>};</div></blockquote><div>=C2=A0<div>Upon verification=
, the appropriate method can be generated from the template for Derived::fu=
nc(int&) and/or Derived::func(double&), depending on which method(s=
) was invoked. </div></div></div></blockquote><div><br></div><div>I'm n=
ot sure what you mean by invoked; you usually have to generate code for all=
the virtual functions unless you can determine that they are never called,=
including through a base class pointer or reference.</div></div></div></di=
v></blockquote><div><br></div><div>Sorry - my bad for using imprecise termi=
nology. You're right that, in general, all versions would have to be cr=
eated by the compiler unless it can determine that a method is never called=
.. I was thinking too far ahead towards optimizations in which you might be =
able to determine that a specific version(s) isn't called once you know=
what the entire program looks like. If you were creating a library, for ex=
ample, you wouldn't be able to apply such optimizations, and every inst=
ance of the derived virtual method would need to be created. Not creating a=
specific method would be the exception, not the rule. Let's just forge=
t that I said anything about this for now.</div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmai=
l_quote"><div>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div><div>Am I missing something? It seems like all of the pieces exist =
for the compiler to be able to handle this type of extension.<br></div></di=
v></div></blockquote><div><br></div><div>What is the motivating use case fo=
r such a feature?</div></div></div></div></blockquote><div><br></div><div>I=
n my particular situation, I had a base class which supported a limited num=
ber of parameter checks on different types. Because C++ doesn't support=
virtual template methods, I had to explicitly enumerate each check. I unde=
rstand that, and my idea doesn't address that restriction.</div><div><b=
r></div><blockquote style=3D"margin: 0 0 0 40px; border: none; padding: 0px=
;"><div>class Base</div><div>{</div><div>=C2=A0 =C2=A0...</div><div>public:=
</div><div>=C2=A0 =C2=A0...</div><div>=C2=A0 =C2=A0virtual bool validatePar=
ameter(const int &) const=3D0;</div><div>=C2=A0 =C2=A0virtual bool vali=
dateParameter(const double &) const=3D0;</div><div>=C2=A0 =C2=A0virtual=
bool validateParameter(const float &) const=3D0;</div><div>=C2=A0 =C2=
=A0...</div><div>};</div></blockquote><div><br></div><div>The checks in the=
derived classes were all the same, except for the type. Each derived type,=
however, had a different check. Thus, I had to write each of the interface=
s for all inheriting classes, and from within each, invoke the template tha=
t actually did the check.</div><div><br></div><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;"><div>class Derived1 : public Base<=
/div><div>{</div><div>=C2=A0 =C2=A0...</div><div>private:</div><div>=C2=A0 =
=C2=A0...</div><div>=C2=A0 =C2=A0template<typename T> bool validatePa=
rameterImpl(const T &t) const { ... };</div><div>=C2=A0 =C2=A0...</div>=
<div>public:</div><div>=C2=A0 =C2=A0...</div><div><div>=C2=A0 =C2=A0bool va=
lidateParameter(const int &i) const final { return validateParameterImp=
l( i ); }</div></div><div><div>=C2=A0 =C2=A0bool validateParameter(const do=
uble &d) const final { return validateParameterImpl( d ); }</div></div>=
<div><div>=C2=A0 =C2=A0bool validateParameter(const float &f) const fin=
al { return validateParameterImpl( f ); }</div></div><div>=C2=A0 =C2=A0...<=
/div><div>};</div></blockquote><div><br></div><blockquote style=3D"margin: =
0 0 0 40px; border: none; padding: 0px;"><div>class Derived2 : public Base<=
/div><div>{</div><div>=C2=A0 =C2=A0...</div><div>private:</div><div>=C2=A0 =
=C2=A0...</div><div>=C2=A0 =C2=A0template<typename T> bool validatePa=
rameterImpl(const T &t) const { ... };</div><div>=C2=A0 =C2=A0...</div>=
<div>public:</div><div>=C2=A0 =C2=A0...</div><div>=C2=A0 =C2=A0bool validat=
eParameter(const int &i) const final { return validateParameterImpl( i =
); }</div><div>=C2=A0 =C2=A0bool validateParameter(const double &d) con=
st final { return validateParameterImpl( d ); }</div><div>=C2=A0 =C2=A0bool=
validateParameter(const float &f) const final { return validateParamet=
erImpl( f ); }</div><div>=C2=A0 =C2=A0...</div><div>};</div></blockquote><d=
iv><br></div><div>If there's ever a need to go back to add a new type t=
o the base class, I'll have to go to each derived class and add a new m=
ethod to it that just invokes the underlying template implementation. All o=
f the information is there for the compiler, so it seems to me that it woul=
d be easier for the programmer, and less error prone, to have the compiler =
do this type of thing automatically:</div><div><br></div><blockquote style=
=3D"margin: 0 0 0 40px; border: none; padding: 0px;"><div><div>class Derive=
d1 : public Base</div></div><div><div>{</div></div><div><div>=C2=A0 =C2=A0.=
...</div></div><div><div>public:</div></div><div><div>=C2=A0 =C2=A0...</div>=
</div><div><div>=C2=A0 =C2=A0template<typename T> bool validateParame=
ter(const T &t) const final { ... }</div></div><div><div>=C2=A0 =C2=A0.=
...</div></div><div><div>};</div></div></blockquote><div><br></div><div>The =
compiler can generate versions of Derived1::validateParameter() for int, do=
uble, and float. If I ever added "char" to Base, for example, the=
compiler would take care of creating that method automatically instead of =
me having to edit each source file to add a new method to each of the deriv=
ed classes.</div><div><br></div><div>The situation is obviously even more c=
omplex if there are multiple levels of hierarchy involved that need to be m=
odified. And if different people wrote the different classes, coordination =
can be a nightmare. Having a template class could significantly reduce ongo=
ing support and reduce the potential for introducing an error as new method=
s are introduced to the base class.</div><div><br></div><div>I work in EDA =
(electronic design automation), and our software is constantly updated as n=
ew rules are created for new IC process nodes. We're in a continuous cy=
cle of code additions as fabs roll out new methodologies, which happens fre=
quently. Anything that can help get away from the copy/paste paradigm that =
junior programers tend to favor can go a long way towards improving code st=
ability and reducing development time. It's not a matter of being lazy.=
If the compiler can do it for us, it would be better to let the compiler d=
o it than to have multiple people go in and out of the code to make these t=
ypes of changes.</div><div><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div dir=3D"ltr"><div>-- <br><div>=C2=A0Nevin ":-)" Liber=
=C2=A0 <mailto:<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-=
mailto=3D"QkUP5yWaFgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'ja=
vascript:';return true;" onclick=3D"this.href=3D'javascript:';r=
eturn true;">ne...@eviloverlord.com</a><wbr>>=C2=A0 (847) 691-1404</div>
</div></div>
</blockquote>
<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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_97_2066318760.1447090813309--
------=_Part_96_1682389510.1447090813309--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 9 Nov 2015 19:52:01 +0200
Raw View
On 9 November 2015 at 19:40, <john.croix@gmail.com> wrote:
>> What is the motivating use case for such a feature?
> The compiler can generate versions of Derived1::validateParameter() for int,
> double, and float. If I ever added "char" to Base, for example, the compiler
> would take care of creating that method automatically instead of me having
> to edit each source file to add a new method to each of the derived classes.
>
> The situation is obviously even more complex if there are multiple levels of
> hierarchy involved that need to be modified. And if different people wrote
> the different classes, coordination can be a nightmare. Having a template
> class could significantly reduce ongoing support and reduce the potential
> for introducing an error as new methods are introduced to the base class.
>
> I work in EDA (electronic design automation), and our software is constantly
> updated as new rules are created for new IC process nodes. We're in a
> continuous cycle of code additions as fabs roll out new methodologies, which
> happens frequently. Anything that can help get away from the copy/paste
> paradigm that junior programers tend to favor can go a long way towards
> improving code stability and reducing development time. It's not a matter of
> being lazy. If the compiler can do it for us, it would be better to let the
> compiler do it than to have multiple people go in and out of the code to
> make these types of changes.
You're talking about a facility that generates interfaces/implementations.
I think you should make your case in SG7, the Reflection Study Group; they
are looking at such problems. I doubt the right solution would be to change
the semantics of member function templates.
--
---
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/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 9 Nov 2015 09:53:13 -0800 (PST)
Raw View
------=_Part_351_368818126.1447091593268
Content-Type: multipart/alternative;
boundary="----=_Part_352_1254536527.1447091593269"
------=_Part_352_1254536527.1447091593269
Content-Type: text/plain; charset=UTF-8
On Monday, November 9, 2015 at 12:40:13 PM UTC-5, john....@gmail.com wrote:
>
>
>
> On Monday, November 9, 2015 at 10:24:52 AM UTC-6, Nevin ":-)" Liber wrote:
>>
>> On 9 November 2015 at 10:09, <john....@gmail.com> wrote:
>>
>>> struct Base
>>> {
>>> virtual void func(int &x);
>>> virtual void func(double &x);
>>> };
>>>
>>> struct Derived : public Base
>>> {
>>> template<typename T> void func(T &x) final;
>>> };
>>>
>>>
>>> Upon verification, the appropriate method can be generated from the
>>> template for Derived::func(int&) and/or Derived::func(double&), depending
>>> on which method(s) was invoked.
>>>
>>
>> I'm not sure what you mean by invoked; you usually have to generate code
>> for all the virtual functions unless you can determine that they are never
>> called, including through a base class pointer or reference.
>>
>
> Sorry - my bad for using imprecise terminology. You're right that, in
> general, all versions would have to be created by the compiler unless it
> can determine that a method is never called. I was thinking too far ahead
> towards optimizations in which you might be able to determine that a
> specific version(s) isn't called once you know what the entire program
> looks like. If you were creating a library, for example, you wouldn't be
> able to apply such optimizations, and every instance of the derived virtual
> method would need to be created. Not creating a specific method would be
> the exception, not the rule. Let's just forget that I said anything about
> this for now.
>
>
>>
>>
>>> Am I missing something? It seems like all of the pieces exist for the
>>> compiler to be able to handle this type of extension.
>>>
>>
>> What is the motivating use case for such a feature?
>>
>
> In my particular situation, I had a base class which supported a limited
> number of parameter checks on different types. Because C++ doesn't support
> virtual template methods, I had to explicitly enumerate each check. I
> understand that, and my idea doesn't address that restriction.
>
The point of making it a virtual interface is so that derived classes can
decide how those checks work, correct? It seems to me that what you need is
some CRTP work:
template<typename derived>
class base
{
public:
//Use SFINAE/concepts to remove this function if the `derived` class does
not implement a corresponding
//const `validate` method that takes a `T`.
template<typename T>
bool validateParameter(const T &t) const
{
self().validate(t);
}
private:
derived &self() {return static_cast<derived&>(*this);}
const derived &self() const {return static_cast<const derived &>(*this);}
};
This avoids the virtual call and lets you use templates to handle things,
both in the base class interface and the derived class.
Of course, your derived class has to do this:
class Derived : public Base<Derived>
{
private:
friend class Base<Derived>;
//Private validation interface.
//Special-case validation.
bool validate(bool b) const;
bool validate(int i) const;
bool validate(const std::string &s) const;
//Can validate other types.
template<typename T>
bool validate(const T& t) const;
};
--
---
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/.
------=_Part_352_1254536527.1447091593269
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, November 9, 2015 at 12:40:13 PM UTC-5, john....@gmail.com wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On Monday, November 9,=
2015 at 10:24:52 AM UTC-6, Nevin ":-)" Liber wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr">On 9 November 2015 at 10:09, <=
span dir=3D"ltr"><<a rel=3D"nofollow">john....@gmail.com</a>></span> =
wrote:<br><div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0=
px"><div>struct Base</div><div>{</div><div>=C2=A0 =C2=A0virtual void func(i=
nt &x);</div><div>=C2=A0 =C2=A0virtual void func(double &x);</div><=
div>};</div><div><br></div><div>struct Derived : public Base</div><div>{</d=
iv><div>=C2=A0 =C2=A0template<typename T> void func(T &x) final;<=
/div><div>};</div></blockquote><div>=C2=A0<div>Upon verification, the appro=
priate method can be generated from the template for Derived::func(int&=
) and/or Derived::func(double&), depending on which method(s) was invok=
ed. </div></div></div></blockquote><div><br></div><div>I'm not sure wha=
t you mean by invoked; you usually have to generate code for all the virtua=
l functions unless you can determine that they are never called, including =
through a base class pointer or reference.</div></div></div></div></blockqu=
ote><div><br></div><div>Sorry - my bad for using imprecise terminology. You=
're right that, in general, all versions would have to be created by th=
e compiler unless it can determine that a method is never called. I was thi=
nking too far ahead towards optimizations in which you might be able to det=
ermine that a specific version(s) isn't called once you know what the e=
ntire program looks like. If you were creating a library, for example, you =
wouldn't be able to apply such optimizations, and every instance of the=
derived virtual method would need to be created. Not creating a specific m=
ethod would be the exception, not the rule. Let's just forget that I sa=
id anything about this for now.</div><div>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>=
=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div>A=
m I missing something? It seems like all of the pieces exist for the compil=
er to be able to handle this type of extension.<br></div></div></div></bloc=
kquote><div><br></div><div>What is the motivating use case for such a featu=
re?</div></div></div></div></blockquote><div><br></div><div>In my particula=
r situation, I had a base class which supported a limited number of paramet=
er checks on different types. Because C++ doesn't support virtual templ=
ate methods, I had to explicitly enumerate each check. I understand that, a=
nd my idea doesn't address that restriction.</div></blockquote><div><br=
>The point of making it a virtual interface is so that derived classes can =
decide how those checks work, correct? It seems to me that what you need is=
some CRTP work:<br><br><div class=3D"prettyprint" style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> derived</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
></span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">base</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">public</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//Use SFINAE/concepts to remove this function if the `derived` =
class does not implement a corresponding</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">//const `validate` method that takes a `T`.<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">template</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> validateParameter</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> T </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">t</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">self</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">().</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">validate</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">private</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 derived </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">self</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">derived</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&>(*</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">this</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> derived </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">self</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">static_cast</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> derived </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">&>(*</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">this</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);}</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</=
span></div></code></div><br>This avoids the virtual call and lets you use t=
emplates to handle things, both in the base class interface and the derived=
class.<br><br>Of course, your derived class has to do this:<br><br><div cl=
ass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Derived</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">public</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">B=
ase</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span style=3D"color: #606;" class=3D"styled-by-prettify">Derived</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">></span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">private</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">friend</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Base</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Derived</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">>;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 </span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">//Private validation =
interface.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>//Special-case validation.</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">bool</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> validate</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> validate</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> i</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> validate</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">string</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br><br>=C2=A0 </span><span style=3D"color: #8=
00;" class=3D"styled-by-prettify">//Can validate other types.</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> validate</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> t<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">};</span></div></code></div><br></div><br>
<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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_352_1254536527.1447091593269--
------=_Part_351_368818126.1447091593268--
.
Author: john.croix@gmail.com
Date: Mon, 9 Nov 2015 11:52:43 -0800 (PST)
Raw View
------=_Part_7051_485815533.1447098763740
Content-Type: multipart/alternative;
boundary="----=_Part_7052_394727486.1447098763740"
------=_Part_7052_394727486.1447098763740
Content-Type: text/plain; charset=UTF-8
On Monday, November 9, 2015 at 11:52:04 AM UTC-6, Ville Voutilainen wrote:
>
> On 9 November 2015 at 19:40, <john....@gmail.com <javascript:>> wrote:
> >> What is the motivating use case for such a feature?
> > The compiler can generate versions of Derived1::validateParameter() for
> int,
> > double, and float. If I ever added "char" to Base, for example, the
> compiler
> > would take care of creating that method automatically instead of me
> having
> > to edit each source file to add a new method to each of the derived
> classes.
> >
> > The situation is obviously even more complex if there are multiple
> levels of
> > hierarchy involved that need to be modified. And if different people
> wrote
> > the different classes, coordination can be a nightmare. Having a
> template
> > class could significantly reduce ongoing support and reduce the
> potential
> > for introducing an error as new methods are introduced to the base
> class.
> >
> > I work in EDA (electronic design automation), and our software is
> constantly
> > updated as new rules are created for new IC process nodes. We're in a
> > continuous cycle of code additions as fabs roll out new methodologies,
> which
> > happens frequently. Anything that can help get away from the copy/paste
> > paradigm that junior programers tend to favor can go a long way towards
> > improving code stability and reducing development time. It's not a
> matter of
> > being lazy. If the compiler can do it for us, it would be better to let
> the
> > compiler do it than to have multiple people go in and out of the code to
> > make these types of changes.
>
>
> You're talking about a facility that generates interfaces/implementations.
> I think you should make your case in SG7, the Reflection Study Group; they
> are looking at such problems. I doubt the right solution would be to
> change
> the semantics of member function templates.
>
Thanks for the suggestion. Will do.
Regards,
John
--
---
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/.
------=_Part_7052_394727486.1447098763740
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Monday, November 9, 2015 at 11:52:04 AM UTC-6, Ville Voutilainen=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 9 November 2015 at 1=
9:40, =C2=A0<<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-ma=
ilto=3D"1w4CM-ieFgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';ret=
urn true;">john....@gmail.com</a>> wrote:
<br>>> What is the motivating use case for such a feature?
<br>> The compiler can generate versions of Derived1::validateParameter(=
) for int,
<br>> double, and float. If I ever added "char" to Base, for e=
xample, the compiler
<br>> would take care of creating that method automatically instead of m=
e having
<br>> to edit each source file to add a new method to each of the derive=
d classes.
<br>>
<br>> The situation is obviously even more complex if there are multiple=
levels of
<br>> hierarchy involved that need to be modified. And if different peop=
le wrote
<br>> the different classes, coordination can be a nightmare. Having a t=
emplate
<br>> class could significantly reduce ongoing support and reduce the po=
tential
<br>> for introducing an error as new methods are introduced to the base=
class.
<br>>
<br>> I work in EDA (electronic design automation), and our software is =
constantly
<br>> updated as new rules are created for new IC process nodes. We'=
re in a
<br>> continuous cycle of code additions as fabs roll out new methodolog=
ies, which
<br>> happens frequently. Anything that can help get away from the copy/=
paste
<br>> paradigm that junior programers tend to favor can go a long way to=
wards
<br>> improving code stability and reducing development time. It's n=
ot a matter of
<br>> being lazy. If the compiler can do it for us, it would be better t=
o let the
<br>> compiler do it than to have multiple people go in and out of the c=
ode to
<br>> make these types of changes.
<br>
<br>
<br>You're talking about a facility that generates interfaces/implement=
ations.
<br>I think you should make your case in SG7, the Reflection Study Group; t=
hey
<br>are looking at such problems. I doubt the right solution would be to ch=
ange
<br>the semantics of member function templates.
<br></blockquote><div><br></div><div>Thanks for the suggestion. Will do.</d=
iv><div><br></div><div>Regards,</div><div>John</div><div>=C2=A0</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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_7052_394727486.1447098763740--
------=_Part_7051_485815533.1447098763740--
.
Author: john.croix@gmail.com
Date: Mon, 9 Nov 2015 11:55:17 -0800 (PST)
Raw View
------=_Part_2720_2079502665.1447098917276
Content-Type: multipart/alternative;
boundary="----=_Part_2721_470348082.1447098917276"
------=_Part_2721_470348082.1447098917276
Content-Type: text/plain; charset=UTF-8
On Monday, November 9, 2015 at 11:53:13 AM UTC-6, Nicol Bolas wrote:
>
> On Monday, November 9, 2015 at 12:40:13 PM UTC-5, john....@gmail.com
> wrote:
>>
>>
>>
>> On Monday, November 9, 2015 at 10:24:52 AM UTC-6, Nevin ":-)" Liber wrote:
>>>
>>> On 9 November 2015 at 10:09, <john....@gmail.com> wrote:
>>>
>>>> struct Base
>>>> {
>>>> virtual void func(int &x);
>>>> virtual void func(double &x);
>>>> };
>>>>
>>>> struct Derived : public Base
>>>> {
>>>> template<typename T> void func(T &x) final;
>>>> };
>>>>
>>>>
>>>> Upon verification, the appropriate method can be generated from the
>>>> template for Derived::func(int&) and/or Derived::func(double&), depending
>>>> on which method(s) was invoked.
>>>>
>>>
>>> I'm not sure what you mean by invoked; you usually have to generate code
>>> for all the virtual functions unless you can determine that they are never
>>> called, including through a base class pointer or reference.
>>>
>>
>> Sorry - my bad for using imprecise terminology. You're right that, in
>> general, all versions would have to be created by the compiler unless it
>> can determine that a method is never called. I was thinking too far ahead
>> towards optimizations in which you might be able to determine that a
>> specific version(s) isn't called once you know what the entire program
>> looks like. If you were creating a library, for example, you wouldn't be
>> able to apply such optimizations, and every instance of the derived virtual
>> method would need to be created. Not creating a specific method would be
>> the exception, not the rule. Let's just forget that I said anything about
>> this for now.
>>
>>
>>>
>>>
>>>> Am I missing something? It seems like all of the pieces exist for the
>>>> compiler to be able to handle this type of extension.
>>>>
>>>
>>> What is the motivating use case for such a feature?
>>>
>>
>> In my particular situation, I had a base class which supported a limited
>> number of parameter checks on different types. Because C++ doesn't support
>> virtual template methods, I had to explicitly enumerate each check. I
>> understand that, and my idea doesn't address that restriction.
>>
>
> The point of making it a virtual interface is so that derived classes can
> decide how those checks work, correct? It seems to me that what you need is
> some CRTP work:
>
> template<typename derived>
> class base
> {
> public:
> //Use SFINAE/concepts to remove this function if the `derived` class
> does not implement a corresponding
> //const `validate` method that takes a `T`.
> template<typename T>
> bool validateParameter(const T &t) const
> {
> self().validate(t);
> }
>
> private:
> derived &self() {return static_cast<derived&>(*this);}
> const derived &self() const {return static_cast<const derived &>(*this
> );}
> };
>
> This avoids the virtual call and lets you use templates to handle things,
> both in the base class interface and the derived class.
>
> Of course, your derived class has to do this:
>
> class Derived : public Base<Derived>
> {
> private:
> friend class Base<Derived>;
>
> //Private validation interface.
> //Special-case validation.
> bool validate(bool b) const;
> bool validate(int i) const;
> bool validate(const std::string &s) const;
>
> //Can validate other types.
> template<typename T>
> bool validate(const T& t) const;
> };
>
>
> Unfortunately that doesn't handle the case of deep hierarchies. What I
presented is a simple case, but if you have a deeper hierarchy, with each
level of hierarchy potentially providing a different implementation, this
approach won't work. Thanks for the suggestion, though.
--
---
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/.
------=_Part_2721_470348082.1447098917276
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br>On Monday, November 9, 2015 at 11:53:13 AM UTC-6, Nicol Bolas wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">On Monday, November 9, 2015 at 12=
:40:13 PM UTC-5, <a>john....@gmail.com</a> wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><br><br>On Monday, November 9, 2015 at 10:24:52 AM UTC-6, Nev=
in ":-)" Liber wrote:<blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr">On 9 November 2015 at 10:09, <span dir=3D"ltr"><<a rel=3D"=
nofollow">john....@gmail.com</a>></span> wrote:<br><div><div class=3D"gm=
ail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote styl=
e=3D"margin:0 0 0 40px;border:none;padding:0px"><div>struct Base</div><div>=
{</div><div>=C2=A0 =C2=A0virtual void func(int &x);</div><div>=C2=A0 =
=C2=A0virtual void func(double &x);</div><div>};</div><div><br></div><d=
iv>struct Derived : public Base</div><div>{</div><div>=C2=A0 =C2=A0template=
<typename T> void func(T &x) final;</div><div>};</div></blockquot=
e><div>=C2=A0<div>Upon verification, the appropriate method can be generate=
d from the template for Derived::func(int&) and/or Derived::func(double=
&), depending on which method(s) was invoked. </div></div></div></block=
quote><div><br></div><div>I'm not sure what you mean by invoked; you us=
ually have to generate code for all the virtual functions unless you can de=
termine that they are never called, including through a base class pointer =
or reference.</div></div></div></div></blockquote><div><br></div><div>Sorry=
- my bad for using imprecise terminology. You're right that, in genera=
l, all versions would have to be created by the compiler unless it can dete=
rmine that a method is never called. I was thinking too far ahead towards o=
ptimizations in which you might be able to determine that a specific versio=
n(s) isn't called once you know what the entire program looks like. If =
you were creating a library, for example, you wouldn't be able to apply=
such optimizations, and every instance of the derived virtual method would=
need to be created. Not creating a specific method would be the exception,=
not the rule. Let's just forget that I said anything about this for no=
w.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"><div>=C2=A0<br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div><div>Am I missing something? It see=
ms like all of the pieces exist for the compiler to be able to handle this =
type of extension.<br></div></div></div></blockquote><div><br></div><div>Wh=
at is the motivating use case for such a feature?</div></div></div></div></=
blockquote><div><br></div><div>In my particular situation, I had a base cla=
ss which supported a limited number of parameter checks on different types.=
Because C++ doesn't support virtual template methods, I had to explici=
tly enumerate each check. I understand that, and my idea doesn't addres=
s that restriction.</div></blockquote><div><br>The point of making it a vir=
tual interface is so that derived classes can decide how those checks work,=
correct? It seems to me that what you need is some CRTP work:<br><br><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code><div><span st=
yle=3D"color:#008">template</span><span style=3D"color:#660"><</span><sp=
an style=3D"color:#008">typename</span><span style=3D"color:#000"> derived<=
/span><span style=3D"color:#660">></span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#008">class</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">base</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br></=
span><span style=3D"color:#008">public</span><span style=3D"color:#660">:</=
span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#800=
">//Use SFINAE/concepts to remove this function if the `derived` class does=
not implement a corresponding</span><span style=3D"color:#000"><br>=C2=A0 =
</span><span style=3D"color:#800">//const `validate` method that takes a `T=
`.</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:=
#008">template</span><span style=3D"color:#660"><</span><span style=3D"c=
olor:#008">typename</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">></span><span style=3D"color:#000"><br>=C2=A0 </span><sp=
an style=3D"color:#008">bool</span><span style=3D"color:#000"> validatePara=
meter</span><span style=3D"color:#660">(</span><span style=3D"color:#008">c=
onst</span><span style=3D"color:#000"> T </span><span style=3D"color:#660">=
&</span><span style=3D"color:#000">t</span><span style=3D"color:#660">)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">const<=
/span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#66=
0">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#008">self</span><span style=3D"color:#660">().</span><span style=
=3D"color:#000">validate</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">t</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#660">}</span><span =
style=3D"color:#000"><br><br></span><span style=3D"color:#008">private</spa=
n><span style=3D"color:#660">:</span><span style=3D"color:#000"><br>=C2=A0 =
derived </span><span style=3D"color:#660">&</span><span style=3D"color:=
#008">self</span><span style=3D"color:#660">()</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#008">=
return</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
static_cast</span><span style=3D"color:#660"><</span><span style=3D"colo=
r:#000">derived</span><span style=3D"color:#660">&>(*</span><span st=
yle=3D"color:#008">this</span><span style=3D"color:#660">);}</span><span st=
yle=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">const</span=
><span style=3D"color:#000"> derived </span><span style=3D"color:#660">&=
;</span><span style=3D"color:#008">self</span><span style=3D"color:#660">()=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">const<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span=
><span style=3D"color:#008">return</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">static_cast</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#008">const</span><span style=3D"color:#000">=
derived </span><span style=3D"color:#660">&>(*</span><span style=3D=
"color:#008">this</span><span style=3D"color:#660">);}</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#660">};</span></div></code></=
div><br>This avoids the virtual call and lets you use templates to handle t=
hings, both in the base class interface and the derived class.<br><br>Of co=
urse, your derived class has to do this:<br><br><div style=3D"background-co=
lor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;borde=
r-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">cla=
ss</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Deri=
ved</span><span style=3D"color:#000"> </span><span style=3D"color:#660">:</=
span><span style=3D"color:#000"> </span><span style=3D"color:#008">public</=
span><span style=3D"color:#000"> </span><span style=3D"color:#606">Base</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">Derived=
</span><span style=3D"color:#660">></span><span style=3D"color:#000"><br=
></span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br><=
/span><span style=3D"color:#008">private</span><span style=3D"color:#660">:=
</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#0=
08">friend</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">class</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Base</span><span style=3D"color:#660"><</span><span style=3D"color:#6=
06">Derived</span><span style=3D"color:#660">>;</span><span style=3D"col=
or:#000"><br><br>=C2=A0 </span><span style=3D"color:#800">//Private validat=
ion interface.</span><span style=3D"color:#000"><br>=C2=A0 </span><span sty=
le=3D"color:#800">//Special-case validation.</span><span style=3D"color:#00=
0"><br>=C2=A0 </span><span style=3D"color:#008">bool</span><span style=3D"c=
olor:#000"> validate</span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">bool</span><span style=3D"color:#000"> b</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">const</span><span style=3D"color:#660">;</span><span style=3D"co=
lor:#000"><br>=C2=A0 </span><span style=3D"color:#008">bool</span><span sty=
le=3D"color:#000"> validate</span><span style=3D"color:#660">(</span><span =
style=3D"color:#008">int</span><span style=3D"color:#000"> i</span><span st=
yle=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">const</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">bool</span><sp=
an style=3D"color:#000"> validate</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#008">const</span><span style=3D"color:#000"> std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#008">string</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">&</spa=
n><span style=3D"color:#000">s</span><span style=3D"color:#660">)</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">const</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"><br><br>=C2=A0 </=
span><span style=3D"color:#800">//Can validate other types.</span><span sty=
le=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">template</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#008">typenam=
e</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">>=
</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#0=
08">bool</span><span style=3D"color:#000"> validate</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#008">const</span><span style=3D"col=
or:#000"> T</span><span style=3D"color:#660">&</span><span style=3D"col=
or:#000"> t</span><span style=3D"color:#660">)</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">const</span><span style=3D"color:#6=
60">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">};</span></div></code></div><br></div><br></blockquote>Unfortunately that=
doesn't handle the case of deep hierarchies. What I presented is a sim=
ple case, but if =C2=A0you have a deeper hierarchy, with each level of hier=
archy potentially providing a different implementation, this approach won&#=
39;t work. Thanks for the suggestion, though.<div>=C2=A0</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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2721_470348082.1447098917276--
------=_Part_2720_2079502665.1447098917276--
.
Author: Peter Sommerlad <peter.sommerlad@hsr.ch>
Date: Mon, 9 Nov 2015 21:22:22 +0100
Raw View
May be having the deep hierarchy is the real problem. Did you do an external design and code review by an expert at least once?
send from a mobile device.
Prof. Peter Sommerlad
peter.Sommerlad@hsr.ch
+41-79-432 23 32
> On 09.11.2015, at 20:55, john.croix@gmail.com wrote:
>
> if you have a deeper hierarchy, with each level of hierarchy potentially providing a different implementation, this approach won't work.
--
---
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/.
.
Author: john.croix@gmail.com
Date: Mon, 9 Nov 2015 13:46:46 -0800 (PST)
Raw View
------=_Part_1505_2134535789.1447105606758
Content-Type: multipart/alternative;
boundary="----=_Part_1506_756802748.1447105606758"
------=_Part_1506_756802748.1447105606758
Content-Type: text/plain; charset=UTF-8
On Monday, November 9, 2015 at 2:22:31 PM UTC-6, PeterSommerlad wrote:
>
> May be having the deep hierarchy is the real problem. Did you do an
> external design and code review by an expert at least once?
>
> send from a mobile device.
> Prof. Peter Sommerlad
> peter.S...@hsr.ch <javascript:>
> +41-79-432 23 32
>
> > On 09.11.2015, at 20:55, john....@gmail.com <javascript:> wrote:
> >
> > if you have a deeper hierarchy, with each level of hierarchy
> potentially providing a different implementation, this approach won't work.
>
I didn't say that this particular example had deep hierarchy. What I said
was that the proposed alternative wouldn't work for hierarchy. In this
case, "deeper" means > 1.
BTW, that's not to say that I'm adverse to code design reviews. In EDA,
though, it's very difficult to start a project from scratch and do an
up-front code design review because we have roughly 1 year between major
releases, and 6 months between minor releases. For this reason, people
often say that EDA software is in perpetual beta because the only time that
the code isn't in flux is when the process node that it was written for is
no longer in use. IC processes are in a continual state of flux, and the
software that has to provide the design masks for those processes has to
track it in as close to real time as possible. The result is that new
layers of software is often built on older layers of software, with changes
as appropriate, sometimes leading to design hierarchies that weren't
originally envisioned. And while various companies, including mine, are
continually looking for ways to improve software quality, the reality is
that there are always going to be junior-level programmers who do stupid
things like copy/paste. To the extent that we can curtail that via compiler
functionality, we'll improve quality and short development and debug time.
--
---
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/.
------=_Part_1506_756802748.1447105606758
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Monday, November 9, 2015 at 2:22:31 PM UTC-6, PeterSommerlad wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">May be having the deep hier=
archy is the real problem. Did you do an external design and code review by=
an expert at least once?
<br>
<br>send from a mobile device.
<br>Prof. Peter Sommerlad
<br><a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"e71v=
5B2nFgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:'=
;return true;" onclick=3D"this.href=3D'javascript:';return true;">p=
eter.S...@hsr.ch</a>
<br>+41-79-432 23 32
<br>
<br>> On 09.11.2015, at 20:55, <a href=3D"javascript:" target=3D"_blank"=
gdf-obfuscated-mailto=3D"e71v5B2nFgAJ" rel=3D"nofollow" onmousedown=3D"thi=
s.href=3D'javascript:';return true;" onclick=3D"this.href=3D'ja=
vascript:';return true;">john....@gmail.com</a> wrote:
<br>>=20
<br>> if =C2=A0you have a deeper hierarchy, with each level of hierarchy=
potentially providing a different implementation, this approach won't =
work.
<br></blockquote><div><br></div><div>I didn't say that this particular =
example had deep hierarchy. What I said was that the proposed alternative w=
ouldn't work for hierarchy. In this case, "deeper" means >=
1.</div><div><br></div><div>BTW, that's not to say that I'm advers=
e to code design reviews. In EDA, though, it's very difficult to start =
a project from scratch and do an up-front code design review because we hav=
e roughly 1 year between major releases, and 6 months between minor release=
s. For this reason, people often say that EDA software is in perpetual beta=
because the only time that the code isn't in flux is when the process =
node that it was written for is no longer in use. IC processes are in a con=
tinual state of flux, and the software that has to provide the design masks=
for those processes has to track it in as close to real time as possible. =
The result is that new layers of software is often built on older layers of=
software, with changes as appropriate, sometimes leading to design hierarc=
hies that weren't originally envisioned. And while various companies, i=
ncluding mine, are continually looking for ways to improve software quality=
, the reality is that there are always going to be junior-level programmers=
who do stupid things like copy/paste. To the extent that we can curtail th=
at via compiler functionality, we'll improve quality and short developm=
ent and debug time.</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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1506_756802748.1447105606758--
------=_Part_1505_2134535789.1447105606758--
.