"A(tmpVector);"和"A tmpVector;"有什么区别?

15

这个问题有以下代码片段:

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) {
}
问题在于A(tmpVector);vector<string> tmpVector;发生了冲突:
error: conflicting declaration 'A  tmpVector'
error: 'tmpVector' has a previous declaration as 'std::vector<std::basic_string<char> > tmpVector'

答案中说:

This

A(tmpVector);

跟这个是一样的

A tmpVector; // 但已经有一个名为tmpVector的对象了

并附上了以下评论:

在这种情况下,()是多余的。

我的问题是:为什么括号是多余的?在C++11规范中是什么让它变得如此?我以前从未见过这种情况。


1
这与C++11无关 http://ideone.com/MFGKSQ - Geoffroy
紧密相关 https://dev59.com/BWAf5IYBdhLWcg3w7mj3 - 101010
基本上又是一个“什么是MVP”的重复问题。 - Bartek Banachewicz
@BartekBanachewicz 真的吗?那是怎么回事? - juanchopanza
1个回答

21

根据标准的§8 [dcl.decl],声明符具有以下语法:

声明符的语法如下:

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 )

(其余语法省略).

特别地,请注意:

  1. ptr-declarator是一个declarator
  2. 形如( ptr-declarator )的东西是一个noptr-declarator,进而是一个ptr-declarator

换句话说,你可以有任意多对括号,它依然是一个声明符。这在像T(x);这样的情况下会导致歧义,但标准的§6.8 [stmt.ambig]解决了这个问题:

在表达式语句和声明之间存在语法歧义:以函数式显式类型转换(5.2.3)作为其最左边子表达式的表达式语句可能与以“(”开头的第一个声明难以区分。在这些情况下,该语句是一个声明。

该段落附带的示例直接涵盖了此情况:

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

1
谢谢,这正是我想要的。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接