看看这里: 在下面的代码中,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;
}
如果有人能够彻底向我解释为什么会存在这样的语法,我将不胜感激:)
感谢。
答案 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>());