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.
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!
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.
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?
> “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)
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.
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'