Topic: decltype(expr) vs. decltype ((expr))


Author: Alp Mestan <alpmestan@gmail.com>
Date: Mon, 1 Jun 2009 12:34:18 CST
Raw View
On 1 juin, 10:33, Sean Hunt <ride...@gmail.com> wrote:
> I think that in some convoluted manner, it actually represents a
> better consistency. decltype(expr) is actually expr, but decltype
> ((expr)) invokes a manner of decay as the expression moves through
> parentheses. I think there's actually another point in the language as
> it stands where something similar happens, but I can't remember
> exactly where (something to do with templates?)

You really do think this is consistent ?
Then decltype((1)) would be different from decltype(1) ? In particular
in C++, I don't think that would be consistent. It could be
understable in functional languages (barely), but not in C++. As I
told, if expr is some complex member-functions call chaining, like
a.foo().bar(arg).foobar(), people can put parens, at least one
additional pair of parens, and then they'd get stuck.

Moreover, what rationale would be given to that ? I mean you'd have to
describe what happens exactly for each additional parens pair you put
around your expr. So except if there is some obvious reason I'm
missing, I really don't think it'd be a good idea.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Mathias Gaunard <loufoque@gmail.com>
Date: Tue, 2 Jun 2009 17:23:41 CST
Raw View
On 28 mai, 04:54, Scott Meyers <use...@aristeia.com> wrote:
> 7.1.6.2 contains this example for decltype:
>
>  struct A { double x; };
>  const A* a = new A();
>
>  decltype(a->x) x3;    // type is double
>  decltype((a->x)) x4;  // type is const double&
>
> Can somebody explain why decltype(expr) is treated differently from
> decltype ((expr))?

That's not really decltype(expr) being different from decltype
((expr)), but rather decltype(obj.member) being different from decltype
(expr), as this type of expression is handled separately.

decltype(expr) with expr an lvalue expression is the type of expr plus
a reference.
This may not be a good idea for identifiers or member accesses (if you
want to return one from a auto -> decltype function for example), so
that's why those cases are handled separately.

However, I do not know why the result of decltype(expr) is such when
expr is an lvalue expression. Easier copy-free forwarding maybe.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Rick Wheeler <rwheeler@oyogeospace.com>
Date: Tue, 2 Jun 2009 17:25:10 CST
Raw View
On Jun 1, 3:33 am, Sean Hunt <ride...@gmail.com> wrote:
> On May 31, 9:21 am, Alp Mestan <alpmes...@gmail.com> wrote:
>
> > On 29 mai, 22:25, Rick Wheeler <rwhee...@oyogeospace.com> wrote:
>
> > > I don't think that answers the question. Moreover as supplemental
> > > commentary, it seems unfortunate and highly contrived to add another
> > > syntactic behavior to parentheses. It should remain true that 'expr'
> > > == '(expr)' == '((expr))'. Couldn't the latter result be achieved as:
>
> > > const decltype(a->x) &x4;  // type is const double&
>
> > It even should/must be achieved this way.
>
> > Whatever expr is, expr must indeed remain equal to (expr), ((expr)),
> > ((((((expr)))))) and so on.
> > Moreover, for me, decltype(e) must just be replaced with the actual
> > type of 'e'. So obtaining a const double& from
>
> I think that in some convoluted manner, it actually represents a
> better consistency. decltype(expr) is actually expr, but decltype
> ((expr)) invokes a manner of decay as the expression moves through
> parentheses. I think there's actually another point in the language as
> it stands where something similar happens, but I can't remember
> exactly where (something to do with templates?)
>
> --
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@netlab.cs.rpi.edu]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

It should be universally agreed that convoluted mannerisms of any kind
are not beneficial to a language. However I see no consistency of any
kind here. Nor do I see any principle of implied decay. Finally, I can
find nothing related to templates that seems germain other than the
new transformation templates, These may offer another explicit
alternative to the one I proposed (e.g. using add_const<>, add[l|r]
value_reference). In fact it seems that these templates offer a truly
complete and "consistent" set of modifications applicable to decltype
expressions. The parens counting grammar should decidedly be abandoned.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Rick Wheeler <rwheeler@oyogeospace.com>
Date: Thu, 4 Jun 2009 21:28:45 CST
Raw View
On Jun 2, 6:23 pm, Mathias Gaunard <loufo...@gmail.com> wrote:
> On 28 mai, 04:54, Scott Meyers <use...@aristeia.com> wrote:
>
> > 7.1.6.2 contains this example for decltype:
>
> >  struct A { double x; };
> >  const A* a = new A();
>
> >  decltype(a->x) x3;    // type is double
> >  decltype((a->x)) x4;  // type is const double&
>
> > Can somebody explain why decltype(expr) is treated differently from
> > decltype ((expr))?
>
> That's not really decltype(expr) being different from decltype
> ((expr)), but rather decltype(obj.member) being different from decltype
> (expr), as this type of expression is handled separately.
>
> decltype(expr) with expr an lvalue expression is the type of expr plus
> a reference.
> This may not be a good idea for identifiers or member accesses (if you
> want to return one from a auto -> decltype function for example), so
> that's why those cases are handled separately.
>
> However, I do not know why the result of decltype(expr) is such when
> expr is an lvalue expression. Easier copy-free forwarding maybe.
>
> --
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@netlab.cs.rpi.edu]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

The differentiation of decltype(expr) vs. decltype(obj.member) in
general is easily recognized. To be clear, Scott's observation has
raised the points here that there is no rationale or construct to
support decltype(obj.member) != decltype((obj.member)). Your right
about the quandry of decltype(e) where e is an lvalue expression. In
fact I can't see the pertinence of that special case or where it
becomes definitively applied. After all, what about:

int i;
decltype(i) x2;


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Jim Hill <gjthill@gmail.com>
Date: Sat, 6 Jun 2009 09:57:58 CST
Raw View
Scott Meyers wrote:
> struct A { double x; };
> const A* a = new A();
>
> decltype(a->x) x3;    // type is double
> decltype((a->x)) x4;  // type is const double&


How else to express the distinction between asking for the type produced by
accessing class member x
specifically through pointer a, and the declared type of member x in the class
a points to?

Jim

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Dragan Milenkovic <dragan@plusplus.rs>
Date: Sat, 6 Jun 2009 16:43:00 CST
Raw View
Jim Hill wrote:
> Scott Meyers wrote:
>> struct A { double x; };
>> const A* a = new A();
>>
>> decltype(a->x) x3;    // type is double
>> decltype((a->x)) x4;  // type is const double&
>
>
> How else to express the distinction between asking for the type produced by
> accessing class member x
> specifically through pointer a, and the declared type of member x in the class
> a points to?

Well, _any_ other way is better than relying on the number of brackets.
How can one even remember which is which? Was it that additional bracket
leads us from the expression to the original declaration? Or does
the additional bracket bring the declared type into the current context?
IMHO, tt's confusing, error prone, ugly...

Even "static decltype(a->x)" would do, although this is not really my
suggestion.

IMHO, this thread should have already moved to the task of finding
a better syntax. If I think of something, I'll speak...

--
Dragan

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Joe Smith" <unknown_kev_cat@hotmail.com>
Date: Sat, 6 Jun 2009 16:42:33 CST
Raw View
"Jim Hill" <gjthill@gmail.com> wrote in message
news:NDmWl.916$u86.538@nwrddc01.gnilink.net...
> Scott Meyers wrote:
>> struct A { double x; };
>> const A* a = new A();
>>
>> decltype(a->x) x3;    // type is double
>> decltype((a->x)) x4;  // type is const double&
>
>
> How else to express the distinction between asking for the type produced
> by
> accessing class member x
> specifically through pointer a, and the declared type of member x in the
> class
> a points to?
>

decltype(A::x)?
or if we really need to do this through pointer a:
or decltype(decltype(*a)::x)?

Could syntax like that not work?


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Faisal Vali <faisalv@gmail.com>
Date: Sun, 7 Jun 2009 20:15:09 CST
Raw View
On Jun 1, 1:34 pm, Alp Mestan <alpmes...@gmail.com> wrote:
> On 1 juin, 10:33, Sean Hunt <ride...@gmail.com> wrote:
>
> > I think that in some convoluted manner, it actually represents a
> > better consistency. decltype(expr) is actually expr, but decltype
> > ((expr)) invokes a manner of decay as the expression moves through
> > parentheses. I think there's actually another point in the language as
> > it stands where something similar happens, but I can't remember
> > exactly where (something to do with templates?)
>
> You really do think this is consistent ?
> Then decltype((1)) would be different from decltype(1) ?

No decltype((1)) is not different from decltype(1) - at least not
based on my reading of the standard.
So for e.g:
#define Ty(x) PrettyPrint(decltype(x))

int main()
{
         int i = 5;
 int&& ri = 6;
 struct L  {
  const double d;  int i;
  L() : d() { }
 };
 L l;
 const L cl;
 Ty(ri);  // int&&
 Ty((ri)); // int&  (named rvalue references are lvalues)
 Ty(i);  //int
 Ty((i)); //int&

 Ty(l.i);  // int
 Ty((l.i)); // int&
 Ty(l.d); // const double
 Ty((l.d)); // const double&

 Ty(cl.i); // int
 Ty((cl.i)); // const int&
 Ty(cl.d); // const double
 Ty((cl.d)); // const double&

 Ty(1);  // int
 Ty((1)); // int

}


> In particular
> in C++, I don't think that would be consistent. It could be
> understable in functional languages (barely), but not in C++. As I
> told, if expr is some complex member-functions call chaining, like
> a.foo().bar(arg).foobar(), people can put parens, at least one
> additional pair of parens, and then they'd get stuck.

Well the a.foo()... expression should always evaluate to the same
thing regardless of parens, because it is a function call.  For e.g.
int foo();
int& rfoo();
int&& rrfoo();

For all of the above, decltype(x()) vs decltype((x())) will always
return the return-type exactly as typed.
[Note: unnamed rvalue references are treated as rvalues NOT lvalues]


>
> Moreover, what rationale would be given to that ? I mean you'd have to
> describe what happens exactly for each additional parens pair you put
> around your expr. So except if there is some obvious reason I'm
> missing, I really don't think it'd be a good idea.
>

I haven't thought about this enough or used this feature enough to
come to a conclusion yet as to how much confusion this will cause, but
I feel I'm with you in spirit - I would have preferred them
introducing a separate operator: ?exprtype?(expr) (with semantics
similar to decltype((e)) and kept decltype(e) consistent regardless of
something as temperamental as a set of parens around the argument).

regards,
Faisal Vali
Radiation Oncology
Loyola




--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@mac.com>
Date: Sun, 7 Jun 2009 20:17:50 CST
Raw View
On Jun 2, 4:25 pm, Rick Wheeler <rwhee...@oyogeospace.com> wrote:
> On Jun 1, 3:33 am, Sean Hunt <ride...@gmail.com> wrote:
> > On May 31, 9:21 am, Alp Mestan <alpmes...@gmail.com> wrote:
> >
> > > Whatever expr is, expr must indeed remain equal to (expr), ((expr)),
> > > ((((((expr)))))) and so on.
> > > Moreover, for me, decltype(e) must just be replaced with the actual
> > > type of 'e'. So obtaining a const double& from
>
> > I think that in some convoluted manner, it actually represents a
> > better consistency. decltype(expr) is actually expr, but decltype
> > ((expr)) invokes a manner of decay as the expression moves through
> > parentheses. I think there's actually another point in the language as
> > it stands where something similar happens, but I can't remember
> > exactly where (something to do with templates?)
>
> It should be universally agreed that convoluted mannerisms of any kind
> are not beneficial to a language.

On the contrary, if C++ is to remain viable as a programming language,
then the language must contain certain subtleties (such as the
difference between decltype(a->x) and decltype((a->x)) - if we are to
have any hope at all in being able to distinguish genuine, C++ experts
from those individuals whose expert knowledge of C++ is entirely
faked. :-)

> However I see no consistency of any
> kind here.

Actually, the effect of the parentheses, while admittedly a little
obscure - does make sense (to me at least). As I interpret the two
expressions, the operand in the first: decltype(a->x) is effectively
the -name- "x". And decltype evaluates a name to its declared type.
The operand in decltype((a->x)), however, is an -unnamed-,
parenthesized expression. Conceptually, the parentheses could be
intepreted as a call to an unnamed function that evaluates the
parenthesized name to its corresponding value. And decltype when
applied to a value (instead of a name) effectively returns the type of
that value in the current program context (So in this this case,
decltype((a->x)) evaluates a const double&, because "a" is a pointer
to a const A object).

Moreover, any C++ programmer who likes to add "extra" pairs of
parenthesis around expressions as a harmless diversion - is already
asking for trouble. In reality, it is important for a programmer to
understand the context of any particular expression and to understand
the effect of any particular construct within that context; because -
depending on the context - adding a pair of parentheses can radically
change the meaning of an expression. For example:

     void f(int); // #1
     void f(int, int); // #2

     ...

     f(2, 3);   // calls #2
     f((2, 3)); // calls #1

Or this example: given a struct "S" and a double variable named "a":

     struct S
     {
         S(int);
     };

     double a = 8.0;

Here are two (slightly) different "w" declarations. The first:

     S w(int(a)); // declares a function named "w"

while the second:

     S w((int(a))); // declares an S variable named "w"

In fact, I would be a lot more comfortable explaining why a pair of
parentheses makes a difference in a decltype expression than I would
explaining why they make a difference in the two "w" declarations
above.

Greg



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Faisal Vali <faisalv@gmail.com>
Date: Sun, 7 Jun 2009 21:53:08 CST
Raw View
On Jun 7, 9:17 pm, Greg Herlihy <gre...@mac.com> wrote:
<snip>
> In fact, I would be a lot more comfortable explaining why a pair of
> parentheses makes a difference in a decltype expression than I would
> explaining why they make a difference in the two "w" declarations
> above.

While you make an excellent point regarding the careless use of
parentheses in C++, it is worth appreciating that many people (some
very good C++ programmers) find it to be just another "vexing" aspect
of C++.  When introducing decltype, if I had had a vote, I would have
voted for not overloading decltype (based on a pair of parentheses
around the argument) to return both the declared type of the
expression and the actual type of the expression in its context of
evaluation.  My vote would have probably gone towards introducing two
separate operators (decltype, ?exprtype?) and keeping their semantics
simple and separate.

regards,
Faisal Vali
Radiation Oncology
Loyola


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Alf P. Steinbach" <alfps@start.no>
Date: Mon, 8 Jun 2009 01:15:42 CST
Raw View
* Greg Herlihy:
> On Jun 2, 4:25 pm, Rick Wheeler <rwhee...@oyogeospace.com> wrote:
>> On Jun 1, 3:33 am, Sean Hunt <ride...@gmail.com> wrote:
>>> On May 31, 9:21 am, Alp Mestan <alpmes...@gmail.com> wrote:
>>>
>>>> Whatever expr is, expr must indeed remain equal to (expr), ((expr)),
>>>> ((((((expr)))))) and so on.
>>>> Moreover, for me, decltype(e) must just be replaced with the actual
>>>> type of 'e'. So obtaining a const double& from
>>> I think that in some convoluted manner, it actually represents a
>>> better consistency. decltype(expr) is actually expr, but decltype
>>> ((expr)) invokes a manner of decay as the expression moves through
>>> parentheses. I think there's actually another point in the language as
>>> it stands where something similar happens, but I can't remember
>>> exactly where (something to do with templates?)
>> It should be universally agreed that convoluted mannerisms of any kind
>> are not beneficial to a language.

I agree with Rick here on principle.

Note: I don't currently have any interest in the details of decltype (yet) and
prefer to not even know what the fuss is all about, technically. It's enough to
know that Yet Another Wart is being introduced into the language. 'typeof', the
existing practice before standardization, was simple... :-)

Of course, by joining this thread I may be forced to delve into the Dirty
Details  --  in order to respond to "hey, u criticizing my fancy car design huh?
how can you say anything anything about the octagonal wheels when u don't
understand the subtleties of the drive transmission, huh?".


> On the contrary, if C++ is to remain viable as a programming language,
> then the language must contain certain subtleties (such as the
> difference between decltype(a->x) and decltype((a->x)) - if we are to
> have any hope at all in being able to distinguish genuine, C++ experts
> from those individuals whose expert knowledge of C++ is entirely
> faked. :-)

Yeah, yeah, but that's what we have 'void main' for.

More subtle gradations are not needed.


>> However I see no consistency of any
>> kind here.
>
> Actually, the effect of the parentheses, while admittedly a little
> obscure - does make sense (to me at least). As I interpret the two
> expressions, the operand in the first: decltype(a->x) is effectively
> the -name- "x". And decltype evaluates a name to its declared type.
> The operand in decltype((a->x)), however, is an -unnamed-,
> parenthesized expression. Conceptually, the parentheses could be
> intepreted as a call to an unnamed function that evaluates the
> parenthesized name to its corresponding value. And decltype when
> applied to a value (instead of a name) effectively returns the type of
> that value in the current program context (So in this this case,
> decltype((a->x)) evaluates a const double&, because "a" is a pointer
> to a const A object).

This somehow reminds me of the rvalues versus lvalue expression subtlety, which,
through endless threads on the subject, it's clear that nobody really understand
(hence, different compilers do it differently, like foo() => rvalue versus
foo().x => what?, OK, Comeau says it's rvalue too, but that consistency of the
abstract ideal rvalue versus lvalue then introduces an inconsistency for the
practical where, silly enough, you can do foo() = S(3) but not foo().x = 3).

Perhaps there should be a rule that unless something can be simply explained so
that it's obviously meaningful and of practical value, *for any simple concrete
example*, then it should never be considered by a standardization committee.

Or, simply, banning idealism not just in standardization work but throughout the
world, only the practical allowed! <g>


> Moreover, any C++ programmer who likes to add "extra" pairs of
> parenthesis around expressions as a harmless diversion - is already
> asking for trouble. In reality, it is important for a programmer to
> understand the context of any particular expression and to understand
> the effect of any particular construct within that context; because -
> depending on the context - adding a pair of parentheses can radically
> change the meaning of an expression. For example:
>
>      void f(int); // #1
>      void f(int, int); // #2
>
>      ...
>
>      f(2, 3);   // calls #2
>      f((2, 3)); // calls #1
>
> Or this example: given a struct "S" and a double variable named "a":
>
>      struct S
>      {
>          S(int);
>      };
>
>      double a = 8.0;
>
> Here are two (slightly) different "w" declarations. The first:
>
>      S w(int(a)); // declares a function named "w"
>
> while the second:
>
>      S w((int(a))); // declares an S variable named "w"
>
> In fact, I would be a lot more comfortable explaining why a pair of
> parentheses makes a difference in a decltype expression than I would
> explaining why they make a difference in the two "w" declarations
> above.

Introducing a YAW-like subtlety into the language in order to save the
programmer from doing things like the first example doesn't quite reach the
level of being meaningful, at least to me.

Having even more cases where parentheses matter do not save the programmer who
doesn't understand that a+b+c is different from a+(b+c) (e.g. wrt. overflow).

The second example above, "the most vexing parse", is a good example why
subtleties and heaping additional meanings onto the already heavily burdened
parentheses, is not a good idea; it's not an example why it's a good idea.


Cheers,

- Alf

--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <usenet@aristeia.com>
Date: Wed, 27 May 2009 20:54:13 CST
Raw View
7.1.6.2 contains this example for decltype:

 struct A { double x; };
 const A* a = new A();

 decltype(a->x) x3;    // type is double
 decltype((a->x)) x4;  // type is const double&

Can somebody explain why decltype(expr) is treated differently from
decltype ((expr))?

Thanks,

Scott

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Sean Hunt <rideau3@gmail.com>
Date: Wed, 27 May 2009 21:26:42 CST
Raw View
On May 27, 8:54 pm, Scott Meyers <use...@aristeia.com> wrote:
> 7.1.6.2 contains this example for decltype:
>
>  struct A { double x; };
>  const A* a = new A();
>
>  decltype(a->x) x3;    // type is double
>  decltype((a->x)) x4;  // type is const double&
>
> Can somebody explain why decltype(expr) is treated differently from
> decltype ((expr))?
>
> Thanks,
>
> Scott

Because if the expression is unparenthesized and an id or a member
access (direct or indirect), then you get the actual declared type of
that variable. This is important in generic code; for instance to
determine if a variable should be included in a copy (no, I can't
think of an actual use case).

Sean Hunt


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Rick Wheeler <rwheeler@oyogeospace.com>
Date: Fri, 29 May 2009 14:25:07 CST
Raw View
On May 27, 10:26 pm, Sean Hunt <ride...@gmail.com> wrote:
> On May 27, 8:54 pm, Scott Meyers <use...@aristeia.com> wrote:
>
> > 7.1.6.2 contains this example for decltype:
>
> >  struct A { double x; };
> >  const A* a = new A();
>
> >  decltype(a->x) x3;    // type is double
> >  decltype((a->x)) x4;  // type is const double&
>
> > Can somebody explain why decltype(expr) is treated differently from
> > decltype ((expr))?
>
> > Thanks,
>
> > Scott
>
> Because if the expression is unparenthesized and an id or a member
> access (direct or indirect), then you get the actual declared type of
> that variable. This is important in generic code; for instance to
> determine if a variable should be included in a copy (no, I can't
> think of an actual use case).
>
> Sean Hunt
>
> --
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@netlab.cs.rpi.edu]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

I don't think that answers the question. Moreover as supplemental
commentary, it seems unfortunate and highly contrived to add another
syntactic behavior to parentheses. It should remain true that 'expr'
== '(expr)' == '((expr))'. Couldn't the latter result be achieved as:

const decltype(a->x) &x4;  // type is const double&

Rick




--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Alp Mestan <alpmestan@gmail.com>
Date: Sun, 31 May 2009 09:21:05 CST
Raw View
On 29 mai, 22:25, Rick Wheeler <rwhee...@oyogeospace.com> wrote:
> I don't think that answers the question. Moreover as supplemental
> commentary, it seems unfortunate and highly contrived to add another
> syntactic behavior to parentheses. It should remain true that 'expr'
> == '(expr)' == '((expr))'. Couldn't the latter result be achieved as:
>
> const decltype(a->x) &x4;  // type is const double&

It even should/must be achieved this way.

Whatever expr is, expr must indeed remain equal to (expr), ((expr)),
((((((expr)))))) and so on.
Moreover, for me, decltype(e) must just be replaced with the actual
type of 'e'. So obtaining a const double& from

const decltype(some_expr_of_type_double) & x;

sounds rather logical.

To conclude, what Scott spotted should really be fixed since if people
using decltype put more parens than needed (people often do that when
they have complex expressions), they could be surprised of the
resulting type, which may lead, depending on the rest of the code, to
compilation errors that would need some time to be fixed, and today
time is money... And such errors would be hard to understand since the
logical way of thinking wouldn't lead them to think extra-parens could
have caused this error, until they come across this discussion via
search engines.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Sean Hunt <rideau3@gmail.com>
Date: Mon, 1 Jun 2009 02:33:36 CST
Raw View
On May 31, 9:21 am, Alp Mestan <alpmes...@gmail.com> wrote:
> On 29 mai, 22:25, Rick Wheeler <rwhee...@oyogeospace.com> wrote:
>
> > I don't think that answers the question. Moreover as supplemental
> > commentary, it seems unfortunate and highly contrived to add another
> > syntactic behavior to parentheses. It should remain true that 'expr'
> > == '(expr)' == '((expr))'. Couldn't the latter result be achieved as:
>
> > const decltype(a->x) &x4;  // type is const double&
>
> It even should/must be achieved this way.
>
> Whatever expr is, expr must indeed remain equal to (expr), ((expr)),
> ((((((expr)))))) and so on.
> Moreover, for me, decltype(e) must just be replaced with the actual
> type of 'e'. So obtaining a const double& from

I think that in some convoluted manner, it actually represents a
better consistency. decltype(expr) is actually expr, but decltype
((expr)) invokes a manner of decay as the expression moves through
parentheses. I think there's actually another point in the language as
it stands where something similar happens, but I can't remember
exactly where (something to do with templates?)


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]