如果我调用" func(const generic& ref)"使用整数作为参数(而不是'泛型'对象),将调用构造函数generic(int _a)来创建新对象。
class generic {
public:
int a;
generic() {}
generic(int _a) : a(_a) {
std::cout << "int constructor was called!";
}
generic(const generic& in) : a(in.a) {
std::cout << "copy constructor was called!";
}
};
void func(const generic& ref) {
std::cout << ref.a;
}
int main() {
generic g(2);
func(g); // this is good.
func(generic(4)); // this is good.
func(8); // this is good...... ?
return 0;
}
最后一个&#34; func(8)&#34; call使用构造函数generic(int _a)创建一个新对象。这种建筑有名字吗?程序员不应该在传递参数之前显式构造一个对象吗?像这样:
func(generic(8));
单独传递整数是否有任何好处(除了节省时间)?
答案 0 :(得分:4)
此行为是overload resolution进程的一部分 - 具体而言。
当您调用func()
时,编译器会构建候选列表。只有一个候选人func(const generic& ref)
,因此编译器会试图找出如何进行呼叫。
它发现没有定义func(int)
,因此它会尝试查找从int
到generic
的转换路径。由于generic
的构造函数采用int
,并且没有其他转换允许执行相同的调用,因此编译器采用构造+调用路径。
编译器按照从高优先级到低优先级的顺序检查三件事:
这意味着签名的完全匹配胜过需要促销的匹配,并且需要促销的匹配胜过需要转化的匹配。
参见&#34;隐式转换序列的排名&#34;上面链接的文档中有关如何应用隐式转换的信息。
答案 1 :(得分:3)
这种建筑有名字吗?程序员不应该在传递参数之前显式构造一个对象吗?
如果您不希望发生这种情况,可以将explicit
specifier添加到构造函数中:
explicit generic(int _a) : a(_a)
{
std::cout << "int constructor was called!";
}
cppreference页面的摘录:
声明没有函数说明符
explicit
的构造函数称为转换构造函数。
默认情况下,在这种情况下允许隐式构造函数调用。
单独传递整数是否有任何好处(除了节省时间)?
根据您编写的代码,无论您是使用func(8)
还是func(generic(8))
调用该方法,都不会更改代码执行的代码。如果您要添加func
的重载,而int
代替generic
,那么调用会突然变得不同。所以,虽然这最终是一个意见问题,但我认为你最好使用func(generic(8))
明确表达。