关于C ++中声明语法的技巧问题

时间:2009-09-04 15:24:13

标签: c++ syntax

看看这里: 在下面的代码中,b的类型是什么?

struct A {
    A (int i) {}
};

struct B {
    B (A a) {}
};

int main () {
    int i = 1;
    B b(A(i)); // what would be the type of b
    return 0;
}

如果有人能够彻底向我解释为什么会存在这样的语法,我将不胜感激:)

感谢。

3 个答案:

答案 0 :(得分:7)

根据C ++标准8.2 / 1,它是一个本地函数声明。您可以使用隐式构造函数来避免这种情况或以下情况:

B b(A(i)); // is equal to B b( A i );

// ---

// to declare variable of type B write:
B b = A(i);
// explicit form if you want:
B b( static_cast<A>(A(i)) );
// or
B b( (A)i );

C ++标准8.2 / 1:

  

由函数式演员与6.8中提到的声明之间的相似性引起的歧义   也可以在声明的上下文中出现。在这种情况下,选择是在函数声明之间   带有参数名称周围的冗余括号和带有函数样式的对象声明   作为初始化者。正如6.8中提到的含糊不清一样,决议是考虑任何问题   可能是声明声明的结构。

答案 1 :(得分:7)

C的一个瑕疵(和C ++继承它(并使其变得更糟))是没有特殊的语法来引入声明。这意味着声明通常看起来像可执行代码。另一个例子:

A * a;

这是将A乘以a,还是声明了什么?为了理解这一行,你必须知道A是一个类型的名称。

C ++中的基本规则是,如果可以将某些内容解析为声明,那么它就是。在这种情况下,它会导致奇怪而令人惊讶的结果。函数声明看起来很像函数调用,特别是(在A之后可以想到几种方式。

您可以在此示例中使用额外的括号来解决此问题,这些括号会删除编译器将代码解析为声明的能力。

B b((A(i)));

在C中,这并不含糊,因为没有构造函数调用的函数样式,因为没有构造函数。 A是类型的名称,或者是函数的名称。它不可能都是。

答案 2 :(得分:5)

B b(A(i)); 

相当于

B b(A i);

- 参数名称周围的括号是可选的 - 相当于

B b(A);

- 参数名称在函数声明中是可选的。因此它是一个函数声明。

通常你会用

进入它
X x();

- 不是预期的默认构造函数 - 但是在使用临时工具时会有更复杂的情况,例如

vector<int> v(istream_iterator<int>(cin), istream_iterator<int>());