转换具有多个参数的构造函数
Converting constructor with multiple arguments
在 C++11 中,没有explicit
关键字的构造函数可用于将参数列表隐式转换为其类。例如:
class Date{
private:
int d, m, y;
public:
Date(int _d, int _m=0, int _y=0) : m(_m), d(_d), y(_y) {}
friend bool operator==(const Date &x, const Date &y) {return x.d==y.d;}
};
int main()
{
Date x = {1,2,3}; // no error; using converting constructor
x == 1; // no error; converting constructor turns int into Date object
x == {1,2,3}; // error
}
对于x == {1,2,3}
,我收到以下错误:
explicit.cc:16:10: error: expected primary-expression before ‘{’ token
x=={1,2,3};
^
我想知道为什么转换构造函数不会将列表{1,2,3}
转换为Date
对象?特别是既然x == 1
不会导致错误,为什么x == {1,2,3}
?
您可能会特别惊讶:
x = {1, 2, 3}; // ok
x == {1, 2, 3}; // error
operator==(x, {1, 2, 3}); // ok
这是因为只有特定的地方允许在语言中使用大括号的初始化列表(基本上是逗号分隔的{}s
之间的内容列表(。它可以放在=
的右侧,因为规则说它可以。它可以用作函数调用表达式中的参数,因为规则说它可以。但它不能用于比较运算符的任何一方,因为规则不允许这样做。
我不知道这背后是否有根本原因,除了可能没有强烈的需求之外。
为了完成Barry的回答,我列出了所有可以出现brace-init-list
的语句或表达式:
- 函数调用:
func({/*...*/},arg2)
- 下标:
obj[{/*...*/}]
; - 显式类型转换:
type{/*...*/}
- 新表达式:
new type{/*...*/}
分配 - 和复合分配:
a = {/*...*/}; b += {/*...*/};...
- 在条件语句的条件下
while (atype i={/*.../*})
- 范围初始值设定项
for(auto it:{/*...*/})
- return 语句:
return {/*.../*}
(如果推导返回类型,则不返回( - 初始值设定项:
atype a{/*...*}; atype b={/*.../*};
或包括成员初始值设定项:a_memb{/*.../*}
- 默认参数
void f(atype a={/*.../*})
我想知道为什么转换构造函数不会将列表
{1,2,3}
转换为Date
对象?
因为它不是"转换构造函数"。它只是"构造函数"。
列表初始化(使用大括号初始化列表时发生的情况(用于从值列表中初始化对象,正如人们可能从名称中期望的那样。x = {1, 2, 3};
不是初始化对象。x
是已初始化的对象。
因此,大括号初始化列表不能直接应用于现有对象;它们只能应用于正在初始化的对象。您要做的是使用该列表初始化Date
然后将该Date
复制到现有的x
对象中。那是拼写x = Date{1, 2, 3};
.
"转换构造函数"是执行隐式转换的构造函数。隐式转换从一种类型的对象转换为另一种类型的对象。列表初始化不是,也从来不是转换操作。Date x = {1, 2, 3};
不会将列表转换为Date
;它使用复制列表初始化规则使用列表初始化Date
。
- C++:使用运算符 = 调用多参数构造函数
- 通过零参数构造函数创建的 glm::mat4 应该包含哪些值?
- 好奇的混合与可变参数构造函数
- 具有默认值的单个参数构造函数是否与默认构造函数相同?
- 为什么我们需要创建一个单参数构造函数来使用临时的无名称对象
- 在可变参数构造函数中初始化常量数组
- C++ 显式多参数构造函数歧义
- 零一参数构造函数
- 可变参数构造函数中的 SFINAE
- 当没有显式关键字与单参数构造函数一起使用时,编译器可以发出警告
- 可变参数类模板和可变参数构造函数
- 确保模板参数类型与其可变参数构造函数的类型匹配
- C++默认参数构造函数与内联初始化优先级
- 如何在 c++ 中将包含复制构造函数的类的参数构造函数称为私有?
- 自动存储中没有无参数构造函数的类对象和异常
- 警告:用两个参数构造函数返回对象时,表达结果未使用
- 如何在C++中调用无参数构造函数
- 在 c++ 中具有多个参数构造函数的模板类存在问题
- 可变参数构造函数优先于用户提供的移动构造函数,除非默认
- 如何从可变参数构造函数参数构造任何对象?