Topic: Namespace structures
Author: Hector <h1rhkh8hmdg3an@gmail.com>
Date: Thu, 24 Sep 2015 21:55:30 -0700 (PDT)
Raw View
------=_Part_2103_1288988011.1443156930039
Content-Type: multipart/alternative;
boundary="----=_Part_2104_754405242.1443156930041"
------=_Part_2104_754405242.1443156930041
Content-Type: text/plain; charset=UTF-8
Namespace structures
I would like to propose a way to extend structures that does not break
current code yet provides a layer of semantics that can be useful for
concepts. This proposal also provides another alternative to those in N4474
<http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4474.pdf>.
Comparison between member functions and free functions
s.f(y)
f(s,y)
- It can only be declared inside the class.
- It must be declared when the class is designed. The design of the
class must foresee applications.
- It can be declared anywhere.
- It can fulfill needs discovered later.
- It can be overloaded if the class is polymorphic and via parameter
promotion.
- It can be overloaded only via parameter promotion.
- It has access to non-public members.
- It can access public members only.
- It is counter-productive to force everything into the OO paradigm
(e.g. 2.sqrt() ).
- It is a step backward to deny the benefits of OO.
Compromise
struct S { int x; };
namespace struct S
{
void f( S & s, int y );
using ::g;
}
- The constructs namespace struct, namespace class, namespace union, and namespace
enum allow to define member functions that are equivalent to public
member functions or public static member function. This name introduction
is prohibited if the size or layout of the original structure would change
( e.g. it might require new entries in the virtual table).
- The namespace constructs also allow the introduction of typedefs,
structures, and templates as long as the new names follow the same rules as
if they were present inside the original structure. For example, a
structure cannot be redefined, functions can be redeclared with the same
parameters, etc.
- Friend declarations are disabled within namespace structures.
- Inline namespaces are allowed within namespace structures.
- The free function f has signature S::f( S &, int ) but it can be
called using the notation s.f(y) as well.
- The function ::g, which must have been declared before, is introduced
in the scope S. If the first parameter is of type S &, then it can be
called using the member notation s.g. Otherwise, g is the equivalent to
a static function S::g.
Advantages:
- Member functions can be declared outside the class.
- It fulfills needs discovered after the class was designed.
- Adding members is no longer an intrusive operation.
- It allows both the OO notation and free-function notation.
- It allows member functions on enumerations.
- It allows a new layer of semantics useful for concepts.
- The declaration of the member function s.f(y) out of S::f( S &, int
) is automatic and intended.
- Implementation should be rather trivial since there are no new look up
rules, just the introduction of extra names in a scope.
Study case
Let us say that the following code was written before the ranged-for loops
were available. Access functions were provided before begin() and end()
were standardized for that purpose. The free function size was written
according to the needs of that time.
class S {
private:
int m_Data[ 10 ];
public:
int * getFirst() const { return m_Data; }
int * getPastLast() const { return m_Data + 10; }
};
int size( const S & a ) { return 10 * sizeof( int ); }
With this proposal, the following code would make class S usable in a
ranged-for loop.
namespace class S {
using begin = getFirst;
using end = getPastLast;
}
The following code adds a size function suitable for containers. This
function returns the number of elements rather than the byte size.
namespace class S {
size_t size( const S & s )
{ return 10; }
}
With the current standard, the same objectives would be achieved with
member functions as follows.
struct T : S {
int * begin() { return getFirst(); }
int * end() { return getPastLast(); }
};
// 3 months later
struct U : T {
size_t size( const S & s )
{ return 10; }
};
The major drawback of the code above is name pollution since every
iteration adds new classes. Free functions pay for name pollution in
different ways.
int * begin( const S & s ) { return s.getFirst(); }
int * end( const S & s ) { return s.getPastLast(); }
size_t forgetWhatTheOldFunctionSizeWas( const S & s ) { return 10; }
Application to Concepts
The examples above show the need of an intermediate layer if old code is to
be reused with concepts. Neither member functions nor free functions might
have the expected names and/or the behavior required in a concept. While
concept maps provide a way to use old code with new algorithms, there is
still the issue of the unified call syntax
<http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4474.pdf>. Namespace
structures would unify the call syntax beyond their usage in concepts. Moreover,
the extra layer afford us different semantics for s.f(y) and f(s,y) within
concepts. For example, I would add the following option 7 to the 6 options
listed in N4474.
Option 7
- If the concept requires s.f(y), then f must have been declared in the
original struct or in a namespace struct (because of the rules, it
cannot be declared in both).
- If the concept requires f(s,y), then the namespace structure function
S::f(s,y) is looked up first then ::f(s,y) is sought as a free function
(up in the namespace tree and its linked spaces).
This option 7 is similar to option 1 in N4474 with one important
difference. Since the unified call syntax applies to functions in the
namespace structure, we avoid the duplication of library functions: both
s.f(y) and f(s,y) match the function S::f( S &, int ) when it exists.
The consideration behind not generalizing s.f(y) to lookup ::f(s,y) (and
viceversa) is to allow for extra flexibility when using old code with the
new algorithms. One cannot assume that functions christened before the
development of concepts will have the expected behavior. N4474 concedes that
If we grant precedence to one resolution (e.g., prefer member over
free-standing function, as done for range-for) or if we select based on
overload resolution, we can easily construct examples that change meaning
compared to status quo.
Conclusion
This proposal creates a hybrid between structures and namespaces. One can
add functions (as well as structures, templates, etc.) to established
structures. It makes them feel more like namespaces, but one retains the
capability of instantiating a namespace structure.
Since this is a new layer, programmers can be encouraged to add functions
into a namespace structure only to make the structure work with a concept.
--
---
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_2104_754405242.1443156930041
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">
<p style=3D"margin:0in;font-family:Calibri;font-size:16.0pt;color:#1E4E79">=
<span style=3D"font-weight:bold">Namespace structures</span></p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">I would like t=
o
propose a way to extend structures that does not break current code yet
provides a layer of semantics that can be useful for concepts. This proposa=
l
also provides another alternative to those in <a href=3D"http://open-std.or=
g/JTC1/SC22/WG21/docs/papers/2015/n4474.pdf">N4474</a>.</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:14.0pt;color:#2E75B5">=
Comparison
between member functions and free functions</p>
<div style=3D"direction:ltr">
<table valign=3D"top" style=3D"direction:ltr;
border-collapse:collapse;border-style:solid;border-color:#A3A3A3;border-wi=
dth:
1pt" border=3D"1" cellpadding=3D"0" cellspacing=3D"0">
<tbody><tr>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.8708in;padding:4pt 4pt 4pt 4pt">
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D3=
1" lang=3D"quz-BO">s.f(y)</p>
</td>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.2444in;padding:4pt 4pt 4pt 4pt">
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D3=
1" lang=3D"quz-BO">f(s,y)</p>
</td>
</tr>
<tr>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.8708in;padding:4pt 4pt 4pt 4pt">
<ul><li><span style=3D"font-family:Calibri;font-size:11.0pt">It can only =
be declared
inside the class.</span></li></ul><ul style=3D"margin-left:.375in;d=
irection:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-to=
p:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calib=
ri;font-size:11.0pt">It must be declared when
the class is designed. The design of the class must foresee
applications.</span></li></ul>
</td>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.2444in;padding:4pt 4pt 4pt 4pt">
<ul><li><span style=3D"font-family:Calibri;font-size:11.0pt">It can be de=
clared
anywhere.</span></li></ul><ul style=3D"margin-left:.375in;direction=
:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-to=
p:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calib=
ri;font-size:11.0pt">It can fulfill needs
discovered later.</span></li></ul>
</td>
</tr>
<tr>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.8708in;padding:4pt 4pt 4pt 4pt">
<ul style=3D"margin-left:0in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibr=
i;font-size:11.0pt">It can be overloaded if
the class is polymorphic and via parameter promotion.</span></li></=
ul>
</td>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.2444in;padding:4pt 4pt 4pt 4pt">
<ul style=3D"margin-left:0in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibr=
i;font-size:11.0pt">It can be overloaded only
via parameter promotion.</span></li></ul>
</td>
</tr>
<tr>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.8708in;padding:4pt 4pt 4pt 4pt">
<ul style=3D"margin-left:0in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibr=
i;font-size:11.0pt">It has access to
non-public members.</span></li></ul>
</td>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.2444in;padding:4pt 4pt 4pt 4pt">
<ul style=3D"margin-left:0in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibr=
i;font-size:11.0pt">It can access public
members only.</span></li></ul>
</td>
</tr>
<tr>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.8708in;padding:4pt 4pt 4pt 4pt">
<ul style=3D"margin-left:0in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibr=
i;font-size:11.0pt" lang=3D"en-US">It is
counter-productive to force everything into the OO paradigm (e.g. <=
/span><span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" l=
ang=3D"quz-BO">2.sqrt()</span><span style=3D"font-family:Calibri;font-size:
11.0pt" lang=3D"en-US"> ).</span></li></ul>
</td>
<td style=3D"border-style:solid;border-color:#A3A3A3;border-width:1pt;
vertical-align:top;width:3.2444in;padding:4pt 4pt 4pt 4pt">
<ul style=3D"margin-left:0in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibr=
i;font-size:11.0pt">It is a step backward to
deny the benefits of OO.</span></li></ul>
</td>
</tr>
</tbody></table>
</div>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:14.0pt;color:#2E75B5">=
Compromise</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">struct S { int x; };</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">namespace struct S</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">{</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">=C2=A0 void f( S & s, int y );</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">=C2=A0 using ::g;</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">}</p>
<ul><li><span style=3D"font-family:Calibri;font-size:11.0pt">The constructs=
</span><span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
>namespace
struct</span><span style=3D"font-family:Calibri;font-size:11.0pt">, </=
span><span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31">na=
mespace
class</span><span style=3D"font-family:Calibri;font-size:11.0pt">, </s=
pan><span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31">nam=
espace
union</span><span style=3D"font-family:Calibri;font-size:11.0pt">, and=
</span><span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
>namespace enum</span><span style=3D"font-family:Calibri;font-size:11.0pt">=
allow to define member
functions that are equivalent to public member functions or public sta=
tic
member function. This name introduction is prohibited if the size or
layout of the original structure would change ( e.g. it might require =
new
entries in the virtual table).</span></li></ul><ul><li><span style=3D"=
font-family:Calibri;font-size:11.0pt">The namespace constructs also
allow the introduction of typedefs, structures, and templates as long =
as
the new names follow the same rules as if they were present inside the
original structure. For example, a structure cannot be redefined,
functions can be redeclared with the same parameters, etc.</span></li>=
</ul><ul><li><span style=3D"font-family:Calibri;font-size:11.0pt">Friend de=
clarations are
disabled within namespace structures.</span></li></ul><ul><li><span st=
yle=3D"font-family:Calibri;font-size:11.0pt">Inline namespaces are allowed
within namespace structures.</span></li></ul><ul><li><span style=3D"fo=
nt-family:Calibri;font-size:11.0pt">The free function </span><span style=3D=
"font-family:Consolas;font-size:10.5pt;color:#ED7D31">f</span><span style=
=3D"font-family:Calibri;font-size:11.0pt"> has signature </span><span style=
=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31">S::f( S &,
int )</span><span style=3D"font-family:Calibri;font-size:11.0pt"> but =
it can
be called using the notation </span><span style=3D"font-family:Consola=
s;
font-size:10.5pt;color:#ED7D31">s.f(y)</span><span style=3D"font-famil=
y:
Calibri;font-size:11.0pt"> as well.</span></li></ul><ul><li><span styl=
e=3D"font-family:Calibri;font-size:11.0pt">The function </span><span style=
=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31">::g</span><span st=
yle=3D"font-family:Calibri;font-size:11.0pt">, which must have been
declared before, is introduced in the scope </span><span style=3D"font=
-family:
Consolas;font-size:10.5pt;color:#ED7D31">S</span><span style=3D"font-f=
amily:
Calibri;font-size:11.0pt">. If the first parameter is of type </span><=
span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31">S &<=
/span><span style=3D"font-family:Calibri;font-size:11.0pt">, then it can be=
called using
the member notation </span><span style=3D"font-family:Consolas;font-si=
ze:
10.5pt;color:#ED7D31">s.g</span><span style=3D"font-family:Calibri;
font-size:11.0pt">. Otherwise, </span><span style=3D"font-family:Conso=
las;
font-size:10.5pt;color:#ED7D31">g</span><span style=3D"font-family:Cal=
ibri;
font-size:11.0pt"> is the equivalent to a static function </span><span=
style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31">S::g</span><=
span style=3D"font-family:Calibri;font-size:11.0pt">.</span></li></ul><p st=
yle=3D"margin:0in;font-family:Calibri;font-size:11.0pt" lang=3D"quz-BO">=C2=
=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:12.0pt;color:#5B9BD5">=
Advantages:</p>
<ul style=3D"margin-left:.375in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top:0;=
margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibri;f=
ont-size:11.0pt">Member functions can be
declared outside the class.</span></li><ul style=3D"margin-left:.375in=
;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"circle"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibr=
i;font-size:11.0pt">It fulfills needs discovered
after the class was designed. </span></li><li style=3D"margin-top:0;m=
argin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibri;fo=
nt-size:11.0pt">Adding members is no longer
an intrusive operation.</span></li></ul><li style=3D"margin-top:0;mar=
gin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibri;font=
-size:11.0pt">It allows both the OO
notation and free-function notation.</span></li><li style=3D"margin-to=
p:0;margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calib=
ri;font-size:11.0pt">It allows member functions on
enumerations.</span></li><li style=3D"margin-top:0;margin-bottom:0;ver=
tical-align:middle"><span style=3D"font-family:Calibri;font-size:11.0pt">It=
allows a new layer of
semantics useful for concepts.</span></li><ul style=3D"margin-left:.37=
5in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"circle"><li style=3D"margin-top=
:0;margin-bottom:0;vertical-align:middle" lang=3D"quz-BO"><span style=3D"fo=
nt-family:Calibri;font-size:11.0pt">The declaration of the
member function </span><span style=3D"font-family:Consolas;font-size:=
10.5pt;
color:#ED7D31">s.f(y)</span><span style=3D"font-family:Calibri;font-s=
ize:
11.0pt"> out of </span><span style=3D"font-family:Consolas;font-size:=
10.5pt;
color:#ED7D31">S::f( S &, int )</span><span style=3D"font-family:=
Calibri;
font-size:11.0pt"> is automatic and </span><span style=3D"font-style:=
italic;
font-family:Calibri;font-size:11.0pt">intended</span><span style=3D"f=
ont-family:Calibri;font-size:11.0pt">.</span></li></ul><li style=3D"margin-=
top:0;margin-bottom:0;vertical-align:middle" lang=3D"quz-BO"><span style=3D=
"font-family:Calibri;font-size:11.0pt">Implementation should be
rather trivial since there are no new look up rules, just the introduc=
tion
of extra names in a scope.</span></li></ul>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt"><br></p>
<p style=3D"margin:0in;font-family:Calibri;font-size:14.0pt;color:#2E75B5">=
Study
case</p>
<p style=3D"margin:0in"><span style=3D"font-family:Calibri;font-size:11.0pt=
" lang=3D"en-US">Let us say that the following code was written before the =
ranged-for
loops were available. Access functions were provided before </span><span st=
yle=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO"=
>begin()</span><span style=3D"font-family:Calibri;font-size:11.0pt" lang=3D=
"en-US"> and </span><span style=3D"font-family:Consolas;font-size:10.5pt;co=
lor:#ED7D31" lang=3D"quz-BO">end()</span><span style=3D"font-family:Calibri=
;font-size:11.0pt" lang=3D"quz-BO"> were standardized for
that purpose. The free function </span><span style=3D"font-family:Consolas;
font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO">size</span><span style=3D"f=
ont-family:
Calibri;font-size:11.0pt" lang=3D"quz-BO"> was written according to the nee=
ds of
that time.</span></p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt" lang=3D"quz-BO=
">=C2=A0</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">class S {</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">private:</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>int m_Data[=
10 ];</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">public:</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>int * getFi=
rst() const {
return m_Data; }</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>int * getPa=
stLast() const {
return m_Data + 10; }</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">};</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">int size( const S & a ) { return 10 * sizeof( int ); }=
</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in"><span style=3D"font-family:Calibri;font-size:11.0pt=
" lang=3D"en-US">With this proposal, the following code would make class </=
span><span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" la=
ng=3D"quz-BO">S</span><span style=3D"font-family:Calibri;font-size:11.0pt" =
lang=3D"en-US"> usable in a ranged-for
loop.</span></p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">namespace class S {</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>using begin=
=3D getFirst;</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>using end =
=3D getPastLast;</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">}</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in"><span style=3D"font-family:Calibri;font-size:11.0pt=
" lang=3D"en-US">The following code adds a </span><span style=3D"font-famil=
y:Consolas;
font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO">size</span><span style=3D"f=
ont-family:
Calibri;font-size:11.0pt" lang=3D"en-US"> function suitable for containers.=
This
function returns the number of elements rather than the byte size.</span></=
p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">namespace class S {</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>size_t size=
( const S &
s )</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>{ return 10=
; }</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">}</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">With the curre=
nt
standard, the same objectives would be achieved with member functions as
follows.</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">struct T : S {</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>int * begin=
() { return
getFirst(); }</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>int * end()=
{ return
getPastLast(); }</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">};</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">// 3 months later</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">struct U : T {</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>size_t size=
( const S &
s )</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO"><span style=3D"mso-spacerun:yes">=C2=A0 </span>{ return 10=
; }</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">};</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">The major draw=
back
of the code above is name pollution since every iteration adds new classes.
Free functions pay for name pollution in different ways.</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">int * begin( const S & s ) { return s.getFirst(); }</p=
>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">int * end( const S & s ) { return s.getPastLast(); }</=
p>
<p style=3D"margin:0in;font-family:Consolas;font-size:10.5pt;color:#ED7D31"=
lang=3D"quz-BO">size_t forgetWhatTheOldFunctionSizeWas( const S & s ) =
{ return
10; }</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:14.0pt;color:#2E75B5">=
Application
to Concepts</p>
<p style=3D"margin:0in"><span style=3D"font-family:Calibri;font-size:11.0pt=
" lang=3D"en-US">The examples above show the need of an intermediate layer =
if old
code is to be reused with concepts. Neither member functions nor free funct=
ions
might have the expected names and/or the behavior required in a concept. Wh=
ile
concept maps provide a way to use old code with new algorithms, there is st=
ill
the issue of the <a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/papers/=
2015/n4474.pdf">unified call syntax</a>.</span><span style=3D"font-family:C=
alibri;font-size:11.0pt" lang=3D"en-US"> </span><span style=3D"font-weight:=
bold;font-family:Calibri;font-size:11.0pt" lang=3D"en-US">Namespace
structures would unify the call syntax beyond their usage in concepts. </sp=
an><span style=3D"font-family:Calibri;font-size:11.0pt" lang=3D"en-US">More=
over, the extra
layer afford us different semantics for </span><span style=3D"font-family:C=
onsolas;
font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO">s.f(y)</span><span style=3D=
"font-family:Calibri;font-size:11.0pt" lang=3D"en-US"> and </span><span sty=
le=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO">=
f(s,y)</span><span style=3D"font-family:Calibri;font-size:11.0pt" lang=3D"e=
n-US"> within concepts. For
example, I would add the following option 7 to the 6 options listed in N447=
4.</span></p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:12.0pt;color:#5B9BD5">=
Option
7</p>
<ul style=3D"margin-left:.375in;direction:ltr;unicode-bidi:embed;
margin-top:0in;margin-bottom:0in" type=3D"disc"><li style=3D"margin-top:0;=
margin-bottom:0;vertical-align:middle"><span style=3D"font-family:Calibri;f=
ont-size:11.0pt" lang=3D"en-US">If the concept
requires </span><span style=3D"font-family:Consolas;font-size:10.5pt;
color:#ED7D31" lang=3D"quz-BO">s.f(y)</span><span style=3D"font-family=
:Calibri;
font-size:11.0pt" lang=3D"en-US">, then </span><span style=3D"font-fam=
ily:Consolas;
font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO">f</span><span style=3D=
"font-family:Calibri;font-size:11.0pt" lang=3D"en-US"> must have been
declared in the original </span><span style=3D"font-family:Consolas;
font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO">struct</span><span sty=
le=3D"font-family:Calibri;font-size:11.0pt" lang=3D"en-US"> or in a </span>=
<span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" lang=3D=
"quz-BO">namespace
struct</span><span style=3D"font-family:Calibri;font-size:11.0pt" lang=
=3D"en-US"> (because of the rules, it cannot be declared in both).</span></=
li><li style=3D"margin-top:0;margin-bottom:0;vertical-align:middle"><span s=
tyle=3D"font-family:Calibri;font-size:11.0pt" lang=3D"en-US">If the concept
requires </span><span style=3D"font-family:Consolas;font-size:10.5pt;
color:#ED7D31" lang=3D"quz-BO">f(s,y)</span><span style=3D"font-family=
:Calibri;
font-size:11.0pt" lang=3D"en-US">, then the namespace structure functi=
on </span><span style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D3=
1" lang=3D"quz-BO">S::f(s,y)</span><span style=3D"font-family:Calibri;font-=
size:11.0pt" lang=3D"quz-BO"> is looked up
first then </span><span style=3D"font-family:Consolas;font-size:10.5pt=
;
color:#ED7D31" lang=3D"quz-BO">::f(s,y)</span><span style=3D"font-fami=
ly:Calibri;
font-size:11.0pt" lang=3D"en-US"> is sought as a free function (up in =
the
namespace tree and its linked spaces).</span></li></ul>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in"><span style=3D"font-family:Calibri;font-size:11.0pt=
" lang=3D"en-US">This option 7 is similar to option 1 in N4474 with one imp=
ortant
difference. Since the unified call syntax applies to functions in the names=
pace
structure, we avoid the duplication of library functions: both </span><span=
style=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" lang=3D"quz-=
BO">s.f(y)</span><span style=3D"font-family:Calibri;font-size:11.0pt" lang=
=3D"quz-BO"> and </span><span style=3D"font-family:Consolas;font-size:10.5p=
t;color:#ED7D31" lang=3D"quz-BO">f(s,y)</span><span style=3D"font-family:Ca=
libri;font-size:11.0pt" lang=3D"quz-BO"> match the function </span><span st=
yle=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO"=
>S::f( S
&, int )</span><span style=3D"font-family:Calibri;font-size:11.0pt" lan=
g=3D"quz-BO"> when it exists.</span></p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in"><span style=3D"font-family:Calibri;font-size:11.0pt=
" lang=3D"en-US">The consideration behind not generalizing </span><span sty=
le=3D"font-family:Consolas;font-size:10.5pt;color:#ED7D31" lang=3D"quz-BO">=
s.f(y)</span><span style=3D"font-family:Calibri;font-size:11.0pt" lang=3D"e=
n-US"> to lookup </span><span style=3D"font-family:Consolas;font-size:10.5p=
t;color:#ED7D31" lang=3D"quz-BO">::f(s,y)</span><span style=3D"font-family:=
Calibri;font-size:11.0pt" lang=3D"en-US"> (and viceversa) is to
allow for extra flexibility when using old code with the new algorithms. On=
e
cannot assume that functions christened before the development of concepts =
will
have the expected behavior. N4474 concedes that</span></p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;margin-left:.375in;font-family:Calibri;font-size:10.=
0pt;
color:#595959">If we grant precedence to one resolution (e.g., prefer membe=
r
over free-standing function, as done for range-for) or if we select based o=
n
overload resolution, we can easily construct examples that change meaning
compared to status quo.</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:14.0pt;color:#2E75B5">=
Conclusion</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">This proposal
creates a hybrid between structures and namespaces. One can add functions (=
as
well as structures, templates, etc.) to established structures. It makes th=
em
feel more like namespaces, but one retains the capability of instantiating =
a
namespace structure.</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">=C2=A0</p>
<p style=3D"margin:0in;font-family:Calibri;font-size:11.0pt">Since this is =
a new
layer, programmers can be encouraged to add functions into a namespace
structure only to make the structure work with a concept.</p>
</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_2104_754405242.1443156930041--
------=_Part_2103_1288988011.1443156930039--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 25 Sep 2015 11:24:46 -0700 (PDT)
Raw View
------=_Part_2035_1703405336.1443205487016
Content-Type: multipart/alternative;
boundary="----=_Part_2036_1460239605.1443205487016"
------=_Part_2036_1460239605.1443205487016
Content-Type: text/plain; charset=UTF-8
Unified function call syntax has no dependency on concepts, nor is it in
any way limited by them. Oh, the paper talks about them in relation to
concepts but only because "Concepts make this (well-known and
long-standing) problem more acute," not because UFC is in any way dependent
on it.
Your idea is ultimately little better than UFC. You can't add virtual
functions to a class that isn't already virtual (as that would affect the
size/layout of the class). You can't add virtual functions to a class that
already has virtual functions, *unless* you're overriding an existing
method (as that would change the number of vtable entries).
Here are what seem the main improvements of your method over UFC:
* Override virtual functions from outside a class.
* Inject operator members that have to be member functions.
However, the latter cases seem... dubious. After all, you don't get to
break encapsulation. So what kind of conversion operator can you inject
into a class if all you have access to are public data? What will your
virtual override actually be able to accomplish without accessing protected
or private data? And so forth.
Ultimately, I see UFC as being far more usable. You can write code today,
which declares "member" functions at namespace scope, that will later allow
your functions to be called with member call syntax. Indeed, the recent C++
guidelines already suggest doing this. Once you get UFC, you won't have to
care whether the function is a member or not. `x.y()` will find it.
Also, if a user wants to bias towards non-member syntax, they can. The
current UFC proposal allows both to work, with only slight differences
between them. Your way is very biased towards member calling, since your
proposal is just to inject members. The only lip-service you play to
non-member calling ultimately requires the user to declare the function as
a *static* member.
Why would you want to do that? It takes a `this`; it's silly to make that
function static.
You also can't make template functions work this way. That is, you can't
define a template function that can be executed on a range of types (either
bound by a concept or not) which can be called using member call syntax.
As I understand it, this would work under UFC syntax:
template<typename T> void SomeFunc(const T &t, ...);
SomeType r;
OtherType v;
r.SomeFunc(...);
v.SomeFunc(...);
Your way would require that I implement `SomeFunc` for each type
explicitly. Unless you're going to suggest `template<typename T> namespace
class T`.
--
---
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_2036_1460239605.1443205487016
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Unified function call syntax has no dependency on concepts=
, nor is it in any way limited by them. Oh, the paper talks about them in r=
elation to concepts but only because "Concepts make this (well-known a=
nd long-standing) problem more acute," not because UFC is in any way d=
ependent on it.<br><br>Your idea is ultimately little better than UFC. You =
can't add virtual functions to a class that isn't already virtual (=
as that would affect the size/layout of the class). You can't add virtu=
al functions to a class that already has virtual functions, <i>unless</i> y=
ou're overriding an existing method (as that would change the number of=
vtable entries).<br><br>Here are what seem the main improvements of your m=
ethod over UFC:<br><br>* Override virtual functions from outside a class.<b=
r><br>* Inject operator members that have to be member functions.<br><br>Ho=
wever, the latter cases seem... dubious. After all, you don't get to br=
eak encapsulation. So what kind of conversion operator can you inject into =
a class if all you have access to are public data? What will your virtual o=
verride actually be able to accomplish without accessing protected or priva=
te data? And so forth.<br><br>Ultimately, I see UFC as being far more usabl=
e. You can write code today, which declares "member" functions at=
namespace scope, that will later allow your functions to be called with me=
mber call syntax. Indeed, the recent C++ guidelines already suggest doing t=
his. Once you get UFC, you won't have to care whether the function is a=
member or not. `x.y()` will find it.<br><br>Also, if a user wants to bias =
towards non-member syntax, they can. The current UFC proposal allows both t=
o work, with only slight differences between them. Your way is very biased =
towards member calling, since your proposal is just to inject members. The =
only lip-service you play to non-member calling ultimately requires the use=
r to declare the function as a <i>static</i> member.<br><br>Why would you w=
ant to do that? It takes a `this`; it's silly to make that function sta=
tic.<br><br>You also can't make template functions work this way. That =
is, you can't define a template function that can be executed on a rang=
e of types (either bound by a concept or not) which can be called using mem=
ber call syntax.<br><br>As I understand it, this would work under UFC synta=
x:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 25=
0, 250); border-color: rgb(187, 187, 187); border-style: solid; border-widt=
h: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">te=
mplate</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">></span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">SomeFunc</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-prettif=
y">&</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: #660;" class=3D"styled-by-prettify">...);</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">SomeType</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> r</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: #606;" class=3D"style=
d-by-prettify">OtherType</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> v</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
><br>r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</s=
pan><span style=3D"color: #606;" class=3D"styled-by-prettify">SomeFunc</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(...);</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>v</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">SomeFunc</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(...);</span></div></code></div><br=
>Your way would require that I implement `SomeFunc` for each type explicitl=
y. Unless you're going to suggest `template<typename T> namespace=
class T`.<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 <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_2036_1460239605.1443205487016--
------=_Part_2035_1703405336.1443205487016--
.
Author: NeoCode <neoprogramming@gmail.com>
Date: Wed, 7 Oct 2015 03:07:04 -0700 (PDT)
Raw View
------=_Part_101_75714487.1444212424366
Content-Type: multipart/alternative;
boundary="----=_Part_102_1891765206.1444212424367"
------=_Part_102_1891765206.1444212424367
Content-Type: text/plain; charset=UTF-8
It's a good idea for other feature: partial class declarations, see
"partial" keyword in C#. We can use "namespace class" and "namespace
struct" keywords for this purpose.
--
---
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_102_1891765206.1444212424367
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">It's a good idea for other feature: partial class decl=
arations, see "partial" keyword in C#. We can use "namespace=
class" and "namespace struct" keywords for this purpose.<br=
><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">
</div></blockquote></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_102_1891765206.1444212424367--
------=_Part_101_75714487.1444212424366--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 7 Oct 2015 13:08:52 +0300
Raw View
On 7 October 2015 at 13:07, NeoCode <neoprogramming@gmail.com> wrote:
> It's a good idea for other feature: partial class declarations, see
> "partial" keyword in C#. We can use "namespace class" and "namespace struct"
> keywords for this purpose.
Or we could just use "partial", since we have context-sensitive
keywords in class-head
already, due to "final".
--
---
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/.
.