我遇到了这个案子(简化)
这个编译没有任何关于它如何将给定参数转换为类A的构造函数中的类B的实例的警告
class B{
public:
B(int _x) { }
virtual ~B() { }
};
class A{
public:
A(const B& source) { }
virtual ~A() { }
};
int main(){
new A(1);
return 0;
}
我没有看到C ++中的任何代码在被要求提供实例/ const引用时给出了构造函数的参数。这是一个不言而喻的规则吗?
当函数原型要求(不是const
)引用时,这不起作用。
编译以下示例:
class B
{
public:
B(double _x = 0, double _y = 0) { }
virtual ~B() { }
};
class A
{
public:
A(const B& source, int z = 0) {cout << "B class constructor";}
A(double _x, double _y){cout << "primitive types";}
virtual ~A() { }
};
int main()
{
new A(1, 1);
return 0;
}
发出警告(使用某些编译器选项):
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
note: candidate 1: A::A(double, double)
note: candidate 2: A::A(const B&, int)
(我知道编译器与int-&gt; double冲突)
但是当从int z = 0
构造函数中删除(const B&, int)
参数时,警告消失(并仍然打印“primitive types
”)
在我看来,这更加含糊不清。
歧义是如何决定的?
答案 0 :(得分:1)
- 这被认为是好习惯吗?
醇>我还没有看到C ++中的任何代码在被要求提供实例/ const引用时给出了构造函数的参数。这是一个不言而喻的规则吗?
&#39;给出构造函数的参数&#39;毫无意义。这里发生的是const B
对象是通过您为此目的提供的构造函数从double
构造的。没有比这更神秘的了。它实际上是一个简单的类型转换操作,如果在传递参数或返回值时可用,C ++编译器将始终考虑单步式类型转换。
- 在没有警告和警告的情况下,这可能/允许的程度如何?
醇>
在某种程度上可以在一个步骤中没有歧义。
当函数原型要求(非常量)引用时,这不起作用。
那是因为编译器不会按照C ++的规则构造非const临时对象。
- 编译器什么时候认为这比重载函数更好? ......在我的选择中更加含糊不清
醇>
不是。
歧义如何解决?
没有歧义可以解决。 C ++中没有规则说它应该尝试用两个或更多参数构造单个const B
对象。