How is 'A(tmpVector);' the same as 'A

2020-02-26 06:57发布

This question has this code snippet:

A::A(const char *pc) {
    A(string(pc));
}

A::A(string s) {
    vector<string> tmpVector;
    tmpVector.push_back(s);
    A(tmpVector); // <-- error
}

// Constructor
A::A(vector<string> filePathVector) {
}

The problem is that A(tmpVector); conflicts with vector<string> tmpVector;:

error: conflicting declaration 'A  tmpVector'
error: 'tmpVector' has a previous declaration as 'std::vector<std::basic_string<char> > tmpVector'

The answer says:

This

A(tmpVector);

is the same as this

A tmpVector; // but there is already an object called tmpVector

With an added comment:

In this context, the () are superfluous.

My question is: why are the parenthesis superfluous? What exactly in the C++11 spec makes that so? I have not seen this before.

标签: c++ c++11
1条回答
▲ chillily
2楼-- · 2020-02-26 07:31

From §8 [dcl.decl] of the standard:

Declarators have the syntax:

declarator:
    ptr-declarator
    noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator:
    noptr-declarator
    ptr-operator ptr-declarator
noptr-declarator:
    declarator-id attribute-specifier-seq_opt
    noptr-declarator parameters-and-qualifiers
    noptr-declarator [ constant-expression_opt] attribute-specifier-seq_opt
    ( ptr-declarator )

(Remainder of grammar omitted).

In particular, note that

  1. A ptr-declarator is a declarator.
  2. Something of the form ( ptr-declarator ) is a noptr-declarator which in turn is a ptr-declarator.

In other words, you can have as many pairs of parentheses as you want and it's still a declarator. Now this causes an ambiguity in cases like T(x);, which is resolved by §6.8 [stmt.ambig] of the standard:

There is an ambiguity in the grammar involving expression-statements and declarations: An expression statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.

The example accompanying that paragraph directly covers this case:

class T {
// ...
public:
    T();
    T(int);
    T(int, int);
};

T(a);        // declaration
T(*b)();     // declaration
T(c)=7;      // declaration
T(d),e,f=3;  // declaration
extern int h;
T(g)(h,2);   // declaration
查看更多
登录 后发表回答