传递给常量引用的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)"调用使用泛型构造函数(int_a)创建一个新对象。这种建筑有名字吗?程序员不应该在传递参数之前显式地构造一个对象吗?像这样:
func(generic(8));
单独传递整数(除了节省时间之外)有什么好处吗?
此行为是重载解决过程的一部分,具体而言。
当您调用func()
时,编译器会构造一个候选列表。只有一个候选func(const generic& ref)
,所以编译器试图弄清楚如何进行调用。
它发现没有定义func(int)
,所以它试图找到从int
到generic
的转换路径。由于generic
的构造函数采用int
,并且没有其他转换允许执行相同的调用,因此编译器采用构造+调用路径。
编译器按照优先级从高到低的顺序检查三件事:
- 完全匹配
- 促销
- 转换
这意味着签名的精确匹配胜过需要升级的匹配,需要升级的比赛胜过需要转换的比赛。
有关如何应用隐式转换的信息,请参阅上面链接的文档的"隐式转换序列排名"。
这种建筑有名字吗?程序员不应该在传递参数之前显式地构造一个对象吗?
如果不希望发生这种情况,可以将explicit
说明符添加到构造函数中:
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))
来明确。
- 常量函数,当其参数是对文字类型的引用时
- 为什么文字不是常量(字符串除外)?
- 模板接受常量,但不接受文字
- C++ 常量指向文字的指针有效吗?
- 为什么对字符串参数的常量引用可以采用字符串文字?
- 字符串文字可以传递给接受常量字符*的函数吗?
- 是否将常量字符*设置为等于字符[]文字安全
- 文字符号和字符串变量之间的串联然后返回常量字符*
- 字符串文字绑定到一个非常量字符指针
- 从文字字符串生成编译时常量整数
- 不以nul结尾的常量字符串文字
- Visual Studio 2015字符串文字并不总是常量
- 其中C++内存中的文字常量存储
- 为什么不允许我将函数返回 const char* 的结果分配给 char*,bt 可以将字符串文字(常量)分配给 cha
- 以前定义的常量,作为宏参数给出,被认为是字符串文字
- 我是否应该为代码中的重复文字定义常量
- 为什么字符常量/文字不能为空?
- 指针和文字常量
- 如何写出像"size_t s = 16 MByte"这样的文字常量?
- 无法在Matlab编码器中传递文字常量