Those are really completely different situations.
B<A> b1(A());
This is a function declaration because it follows the syntax production "return-type identifier '(' parameter-declaration-list ')'", where parameter-declaration-list is a comma-separated list of parameter-declarations. The production for such a declaration is "type abstract-declarator[opt]". An abstract-declarator can, among other things, be empty, or "'(' abstract-declarator ')'". So "A()" matches a type (A) followed by the parentheses form of abstract-declarator containing the empty form of abstract-declarator. Thus, the code is syntactically a valid function declaration and is parsed as such.
B<A> b1((A()));
Here, if we want to go the function declaration route, we need to match "(A())" to parameter-declaration; however, there is no way to do this. So this isn't a function declaration, and therefore must be a variable declaration with a direct-initializer.
The other situation is grammatically unambiguous. Both decltype(i) and decltype((i)) are simple decltype derivations. In the first case, the syntax tree is DeclType( DeclRefExpression("i") ), in the second, it's DeclType( ParenExpression( DeclRefExpression("i") ) ).
The special part here are the rules for decltype. The decltype rules are as follows:
- If the expression is a function call, the result of decltype is the declared type of that function. E.g. given "int foo()", decltype(foo()) is "int". Given "int& foo()", decltype(foo()) is "int&".
- If the expression is a declaration reference expression, the result of decltype is the declared type of that declaration. Given "int i", decltype(i) is "int". Given "int& i", decltype(i) is "int&".
- If neither of the above applies and the expression is an lvalue, the result of decltype is an lvalue reference to the type of the expression. If the expression is an lvalue of type int, the result is "int&".
- If none of the above rules apply, the result of decltype is the type of the expression. If the expression is an rvalue of type int, the result is "int".
In decltype(i), the expression is a declref to i. The type of i is int. Thus, decltype(i) is "int".
In decltype((i)), the expression is a parenexpr. It doesn't matter what the parentheses contain - neither rule 1 nor 2 can apply. However, (i) is an lvalue, so rule 3 applies. The type of (i) is int, so decltype((i)) is "int&".