传递给 const 引用的 C++ 文字会导致自动构造
C++ literal passed to const reference leads to automatic construction
如果我使用一个整数作为参数(而不是 'generic' 对象)调用 "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;
}
最后的 "func(8)" 调用使用构造函数 generic(int _a) 创建了一个新对象。这种建筑有名字吗?程序员不应该在传递参数之前显式构造一个对象吗?像这样:
func(generic(8));
单独传递整数是否有任何好处(除了节省时间)?
Is there a name for this kind of construction? Shouldn't the programmer explicitly construct an object before passing the argument?
如果您不希望这种情况发生,您可以将 explicit
specifier 添加到您的构造函数中:
explicit generic(int _a) : a(_a)
{
std::cout << "int constructor was called!";
}
cppreference 页面的摘录:
A constructor that is declared without the function specifier explicit
is called a converting constructor.
默认情况下,在这种情况下允许隐式构造函数调用。
Is there any benefit in passing the integer alone (other than saving time)?
无论您使用 func(8)
还是 func(generic(8))
调用该方法都不会改变执行的代码 给定您编写的代码。如果您要添加一个 func
的重载,它采用 int
而不是 generic
,那么调用会突然变得不同。因此,尽管这最终是一个见仁见智的问题,但我认为您最好使用 func(generic(8))
.
来明确说明
此行为是 overload resolution 过程的一部分 - 特别是。
当您调用 func()
时,编译器会构建一个候选列表。只有一个候选项,func(const generic& ref)
,因此编译器试图弄清楚如何进行调用。
它看到没有定义func(int)
,所以它试图找到从int
到generic
的转换路径。由于 generic
的构造函数采用 int
,并且没有其他转换允许执行相同的调用,因此编译器采用构造+调用路径。
编译器按照优先级从高到低的顺序检查三件事:
- 完全匹配
- 晋升
- 转化
这意味着签名的完全匹配胜过需要升级的匹配,而需要升级的匹配胜过需要转换的匹配。
有关如何应用隐式转换的信息,请参阅上面链接的文档的 "Ranking of implicit conversion sequences"。
如果我使用一个整数作为参数(而不是 'generic' 对象)调用 "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;
}
最后的 "func(8)" 调用使用构造函数 generic(int _a) 创建了一个新对象。这种建筑有名字吗?程序员不应该在传递参数之前显式构造一个对象吗?像这样:
func(generic(8));
单独传递整数是否有任何好处(除了节省时间)?
Is there a name for this kind of construction? Shouldn't the programmer explicitly construct an object before passing the argument?
如果您不希望这种情况发生,您可以将 explicit
specifier 添加到您的构造函数中:
explicit generic(int _a) : a(_a)
{
std::cout << "int constructor was called!";
}
cppreference 页面的摘录:
A constructor that is declared without the function specifier
explicit
is called a converting constructor.
默认情况下,在这种情况下允许隐式构造函数调用。
Is there any benefit in passing the integer alone (other than saving time)?
无论您使用 func(8)
还是 func(generic(8))
调用该方法都不会改变执行的代码 给定您编写的代码。如果您要添加一个 func
的重载,它采用 int
而不是 generic
,那么调用会突然变得不同。因此,尽管这最终是一个见仁见智的问题,但我认为您最好使用 func(generic(8))
.
此行为是 overload resolution 过程的一部分 - 特别是。
当您调用 func()
时,编译器会构建一个候选列表。只有一个候选项,func(const generic& ref)
,因此编译器试图弄清楚如何进行调用。
它看到没有定义func(int)
,所以它试图找到从int
到generic
的转换路径。由于 generic
的构造函数采用 int
,并且没有其他转换允许执行相同的调用,因此编译器采用构造+调用路径。
编译器按照优先级从高到低的顺序检查三件事:
- 完全匹配
- 晋升
- 转化
这意味着签名的完全匹配胜过需要升级的匹配,而需要升级的匹配胜过需要转换的匹配。
有关如何应用隐式转换的信息,请参阅上面链接的文档的 "Ranking of implicit conversion sequences"。