decltype in c+0x and parentheses

Jun 9, 2012 at 3:58am
1
2
int i=6;
decltype((i)) var5 = i;      // int&  

I just didn't understand why 'i' which is in parentheses is regarded as Lvalue, now, i knew the application of the parentheses until i found that in MSDN:The inner parentheses cause the statement to be evaluated as an expression instead of a member access.(http://msdn.microsoft.com/en-us/library/dd537655.aspx), and i also didn't understand a question i didn't comprehend for a long time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct A
{
  A(){}
};
template<typename T>
class B
{
public:
    B(T t){printf("B\n");}

};
template <typename T >
void ft(T t)
{
    t.f();
}
int _tmain(int argc, _TCHAR* argv[])
{
    B<A> b1(A());   //one function declaration, A() is regarded as fun-ptr, and b1 is a function
    B<A> b2((A())); //A() is regarded as anonymous object.
    return 0;   
}




Why A() is regarded as anonymous object when put it in parentheses as (A()). the inner parentheses explanation about decltype in MSDN can't apply to this situation. could someone tell me that is there a expanation about the parentheses function in this two situation in C++ standard. How should i understand this better, appreciate it very much!
Last edited on Jun 9, 2012 at 4:09am
Jun 9, 2012 at 6:28am
Line 19 declares a function. This is colloquially known as "Most Vexing Parse" (see Effective C++ or just google.
Line 20 declares an object. The parentheses are a common way to avoid MVP.

Decltype has nothing to do with this. MVP is a C++98 feature.
Last edited on Jun 9, 2012 at 6:30am
Jun 9, 2012 at 6:56am
> B<A> b1(A());

A() is a type (nullary function returning A)
( A() ) is not a type; it is an expression (because of the parenthesis around it)

In C++11, disambiguation is easy if we use the uniform initialization syntax:

1
2
3
B<A> b1 { A() } ; // A() can't be a type here

decltype( A() ) x ; // here too, A() can't be a type 

Jun 9, 2012 at 7:11am
Thanks for your help. But how to understand “The inner parentheses cause the statement to be evaluated as an expression instead of a member access”.
Does it need to be treated as a rule?
Jun 9, 2012 at 7:25am
> “The inner parentheses cause the statement to be evaluated as an expression instead of a member access”.
> Does it need to be treated as a rule

I suppose so. Or else, the parsing precedence rules would apply.
1
2
3
4
5
6
char srce[] = "hello world" ;
char dest[100] ;
std::strcpy( dest, srce ) ; // ok, call of std::strcpy with two arguments

std::strcpy( ( dest, srce ) ) ; // ***error, call of std::strcpy with only one argument
// ( dest, srce ) is an expression; (in which the comma is the sequencing operator) 
Last edited on Jun 9, 2012 at 7:26am
Jun 9, 2012 at 7:54am
Here is the other situation:
1
2
3
4
5
bool func(){
    return false;
}

decltype((func())) ;    // bool, parentheses around f() are ignored 

I am a little confused.
Jun 9, 2012 at 8:15am
> bool, parentheses around f() are ignored

Yes, because in decltype(e), e is always evaluated as an expression.

In decltype(expression),
if expression is a function call or an invocation of an overloaded operator (parentheses around expression are ignored), decltype(expression) is the return type of the statically chosen function.


For several annotated examples: http://pic.dhe.ibm.com/infocenter/comphelp/v111v131/topic/com.ibm.xlcpp111.aix.doc/language_ref/decltype.html
Jun 9, 2012 at 8:48am
in your link,for "General rules for using decltype" says, an expression only match the 3rd rule can make itself to T&,
but for:
1
2
int i=6;
decltype((i)); //reference type 


i cannot see how do it match the 3rd rule .
Jun 9, 2012 at 2:38pm
The type denoted by decltype(e) is defined as follows:

rule 1: if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named by e.

rule 2: otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;

rule 3: otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

rule 4: otherwise, decltype(e) is the type of e.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int i = 9 ;
int foo() ; // function returning int

decltype(i) a ; // i is is an unparenthesized id-expression
// rule 1. type of 'a' is 'int'

decltype( ++i ) b = i ; // the expression ++i is an an lvalue of type 'int'
// rule 3. type of 'b' is 'reference to int'
// note: like in sizeof(++i), ++i is not evaluated at run-time

decltype( (i) ) c = i ; // the expression (i) is an an lvalue of type 'int'
// rule 3. type of 'c' is 'reference to int'

decltype( foo() ) d ; // the expression foo() is an an rvalue of type 'int'
// rule 4. type of 'd' is 'int'
// note: like in sizeof( foo() ), foo() is not evaluated at run-time

decltype( ( foo() ) ) e ; // the expression ( foo() ) is an an rvalue of type 'int'
// rule 4. type of 'e' is 'int'
// note: foo() is not evaluated at run-time

decltype( +i ) f ; // the expression +i is an an rvalue of type 'int'
// rule 4. type of 'f' is 'int'

decltype( (+i) ) g ; // the expression (+i) is an an rvalue of type 'int'
// rule 4. type of 'g' is 'int'

decltype( std::move(i) ) h = i+3 ; // the expression std::move(i) is an xvalue of type 'int'
// rule 2. type of 'h' is 'rvalue-reference to int' 

Jun 9, 2012 at 4:38pm
decltype( ++i ) b = i ; ++i is an expression and unparenthesized why should it match the rule 1?

And I know so little that I do not know the expression of '+i'.What‘s the significance of this expression
Last edited on Jun 9, 2012 at 5:48pm
Jun 9, 2012 at 7:29pm
++i is not an id-expression
+i is (for built-in operator+) the decayed and promoted i.
Last edited on Jun 9, 2012 at 7:32pm
Jun 10, 2012 at 12:34pm
Is ’+i‘ ‘s left operand 0 ?
Jun 10, 2012 at 2:08pm
In +i, the + is the unary plus operator.

With short s = 0 ;, +s is an rvalue of type int. The unary + operator always applies promotions where applicable and always yields an rvalue.
Jun 12, 2012 at 2:23am
Thank you for helping to solve all the puzzles .I appreciate that very much.
Topic archived. No new replies allowed.