From: CornedBee on 25 May 2010 03:55 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 25 May 2010 03:56 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 25 May 2010 03:54
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! ] |