传递给const引用的C ++文字导致自动构造

时间:2015-11-30 18:54:21

标签: c++ c++11 reference const literals

如果我调用" 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));

单独传递整数是否有任何好处(除了节省时间)?

2 个答案:

答案 0 :(得分:4)

此行为是overload resolution进程的一部分 - 具体而言。

当您调用func()时,编译器会构建候选列表。只有一个候选人func(const generic& ref),因此编译器会试图找出如何进行呼叫。

它发现没有定义func(int),因此它会尝试查找从intgeneric的转换路径。由于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))明确表达。