From: CornedBee on
On May 24, 5:45 pm, ManicQin <manic...(a)gmail.com> wrote:
> Hello everybody.
> In Scott Meyers lecture notes he states that one of the differences
> between Auto and decltype is that the decltype does not evaluate the
> expression.
>
> I have a question regarding the evaluation of the expression, in the
> next scenario what should I expect:
>
>
> int main()
> {
> B* tmp = new D();
> auto test1 = tmp->Clone(); //returns D*!!!
> decltype(tmp->Clone()) test2 = tmp->Clone();
> return 0;
>
> }
>
> Please note That D::Clone overloads with a different return type.
>
> In my understanding if the "auto" is evaluating so it means that the
> type of test1 should be D*, but VS10 understands different :) what am
> I missing?

You misunderstand what "evaluating" means. Both auto and decltype
determine types at compile time, so they can only use static type
information. Static type information says that the return type of tmp-
>Clone() is a B*, so both test1 and test2 are B*.

Evaluating is about whether the expression is actually computed at run
time. In your example, Clone() will be called twice during the
execution of the program. Once for the initializer of test1, once more
for the initializer of test2, but *not* for the expression within
decltype().

Sebastian


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Stuart Golodetz on
Paul Bibbings wrote:
> ManicQin <manicqin(a)gmail.com> writes:
>
>> Hello everybody.
>> In Scott Meyers lecture notes he states that one of the differences
>> between Auto and decltype is that the decltype does not evaluate the
>> expression.
>>
>> I have a question regarding the evaluation of the expression, in the
>> next scenario what should I expect:
>>
>> class B
>> {
>> public:
>> B()
>> {
>>
>> }
>> virtual B* Clone()
>> {
>> cout << "B" << endl;
>> return new B();
>> }
>> };
>>
>> class D : public B
>> {
>> public:
>> D(){}
>> virtual D* Clone()
>> {
>> cout << "D" << endl;
>> return new D();
>> }
>> };
>>
>> int main()
>> {
>> B* tmp = new D();
>> auto test1 = tmp->Clone(); //returns D*!!!
>> decltype(tmp->Clone()) test2 = tmp->Clone();
>> return 0;
>> }
>>
>> Please note That D::Clone overloads with a different return type.
>>
>> In my understanding if the "auto" is evaluating so it means that the
>> type of test1 should be D*, but VS10 understands different :) what am
>> I missing?
>
> To my understanding, the type of test2 will be B* owing to:
>
> [dcl.type.simple]/4
> "The type denoted by decltype(e) is defined as follows:
> // ...
> - otherwise, if e is a function call (5.2.2) or an invocation of an
> overloaded operator (parentheses around e are ignored), decltype(e)
> is the return type of the statically chosen function."
>
> Now, when it comes to your application of the auto specifier,
> effectively we need to apply a process corresponding template argument
> deduction (see [dcl.spec.auto]/6) to follow it through, one which, IIUC,
> requires that, for:
>
> auto test1 = tmp->Clone();
>
> "The type of [test1] is the deduced type of the parameter u in the
> call f(expr) [for expr = tmp->Clone()] of the following invented
> function template:
>
> template <class U> void f(const U& u)"
>
> Unfortunately, I am not yet able to find my way through the details
> fully in the C++0x FCD, but applying this by way of example:
>
> 22:12:33 Paul Bibbings(a)JIJOU
> /cygdrive/d/CPPProjects/CLCPPM $cat auto_decl.cpp
> class B
> {
> public:
> virtual B * Clone() { return new B(); }
> };
>
> class D : public B
> {
> public:
> virtual D * Clone() { return new D(); }
> };
>
> template <class U> void f(const U& u) { }
>
> int main()
> {
> B* b = new D();
> f(b->Clone());
> }
>
> 22:12:38 Paul Bibbings(a)JIJOU
> /cygdrive/d/CPPProjects/CLCPPM $gcc -std=c++0x -c auto_decl.cpp
>
> 22:12:54 Paul Bibbings(a)JIJOU
> /cygdrive/d/CPPProjects/CLCPPM $nm --demangle auto_decl.o | grep f\<
> 00000000 T void f<B*>(B* const&)
>
> you'll see that this process of template argument deduction again
> deduces according to the return type considered statically.
>
> If this is the case, as it apparently it is, it would seem that the
> notion of decltype(expr) providing an unevaluated context whereas auto
> *does* `evaluate' in some sense (although I'm not quite sure of the exact
> sense of Meyers' purported idea here) is not actually the factor that
> decides it.
>
> Having said this, again, a quote from Meyers would help here.
>
> Regards
>
> Paul Bibbings

As I understand it, all that's being said is that in:

auto var1 = expr1;
decltype(expr2) var2 = expr3;

expr2 is *not* evaluated at run-time. However, both expr1 and expr3
*are* evaluated. Evaluation of the values of the expressions at run-time
is not the same as deduction of their types. The *types* of expr1 and
expr2 are worked out at compile-time and given to var1 and var2,
respectively.

These two give var the same type:

1) auto var = e;
2) decltype(e) var = e;

In both 1) and 2), e is evaluated at run-time (i.e. the e on the RHS of
the assignment gets evaluated in each case). However, the e within
decltype(e) in 2) doesn't get evaluated - it is only used at
*compile-time* to deduce the type of var. (And the deduction process
does not involve evaluating it, natch.)

Phew! Think that makes sense...

Stu

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Nick Hounsome on
On 24 May, 16:45, ManicQin <manic...(a)gmail.com> wrote:
> Hello everybody.
> In Scott Meyers lecture notes he states that one of the differences
> between Auto and decltype is that the decltype does not evaluate the
> expression.
>
> I have a question regarding the evaluation of the expression, in the
> next scenario what should I expect:
>
> class B
> {
> public:
> B()
> {
>
> }
> virtual B* Clone()
> {
> cout << "B" << endl;
> return new B();
> }
>
> };
>
> class D : public B
> {
> public:
> D(){}
> virtual D* Clone()
> {
> cout << "D" << endl;
> return new D();
> }
>
> };
>
> int main()
> {
> B* tmp = new D();
> auto test1 = tmp->Clone(); //returns D*!!!
> decltype(tmp->Clone()) test2 = tmp->Clone();
> return 0;
>
> }
>
> Please note That D::Clone overloads with a different return type.
>
> In my understanding if the "auto" is evaluating so it means that the
> type of test1 should be D*, but VS10 understands different :) what am
> I missing?

It's evaluated at runtime - The type is still the compile time return
type of B::Clone() i.e. B*.

All it means is that if you need an uninitialized variable you have to
use decltype.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]