在带有转换运算符的初始值设定项的情况下,复制列表初始化的假定行为是什么
What is the supposed behavior of copy-list-initialization in the case of an initializer with a conversion operator?
class AAA {
public:
AAA() {}
AAA(const AAA&) {}
};
class BBB {
public:
BBB() {}
operator AAA() { AAA a; return a; }
};
int main() {
BBB b;
AAA a = {b};
}
上面的代码是在g++和vc++上编译的,但不是clang++
传统语法AAA a = b;
在这三个方面都可以编译。
class AAA {};
class BBB {
public:
BBB() {}
operator AAA() { AAA a; return a; }
};
int main() {
BBB b;
AAA a = {b};
}
上面的代码没有在g++、vc++、clang++中的任何一个上编译。与第一个代码片段的唯一区别是,我删除了AAA的两个用户提供的构造函数
同样,传统语法AAA a = b;
在这三个方面都可以编译。
我确信,在带有转换运算符的初始化器的情况下,复制初始化的传统语法是定义良好的。但对于C++11副本列表初始化,我感到困惑。clang是采取正确的操作拒绝初始化,还是g++/vc++采取正确的行动接受初始化(如第一个代码片段所示)?为什么第二个代码片段中所做的如此琐碎的更改会导致显著的不同行为?毕竟,在这种情况下,复制列表初始化和传统的复制初始化之间有什么区别?
编辑:添加第三种情况:
class CCC {};
class AAA {
public:
AAA() {}
AAA(const AAA&) {}
AAA(const CCC&) {}
};
class BBB {
public:
BBB() {}
operator CCC() {CCC c; return c;}
};
int main() {
BBB b;
AAA a = {b};
}
以上代码可用于所有三个编译器。如果最终目标构造函数不是复制构造函数,转换运算符是否有效
在这种情况下,传统语法AAA a = b;
无法按预期编译这三个语法,因为传统的副本初始化在到达最终副本构造函数之前最多允许一个级别的用户定义隐式转换(最终目的地只能是副本构造函数)。
乞求对所有这些混乱做出系统的解释。。。
对于第一个http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1673(请参阅上一个测试用例):如果列表初始化只将单个元素传递给某个类X
的复制/移动构造函数,则不允许对该单个元素进行用户定义的转换以将其转换为X
参数。另请参阅http://llvm.org/bugs/show_bug.cgi?id=12117是什么让Clang实现了这个规则
第二:你在击球http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1467(但不是使用相同类型的对象,而是使用不相关类型的对象)。您的聚合根本不提供BBB
类型的数据成员。
对于第三种情况:以上两种情况都不适用,因此列表初始化工作,并调用AAA
的CCC
构造函数。= b
初始化失败,因为只允许尝试在单个用户定义的转换序列中将b
转换为AAA
。但在这里,您需要首先转换为CCC
,然后再次转换为AAA
。对于列表初始化,不存在只进行一次用户定义转换的限制。
- 复制列表初始化的隐式转换的等级是多少
- 链表,将列表复制到另一个列表
- 我可以从列表中获取对象并复制它们,但如何删除我复制的对象?
- C++完全复制要字符串的字符列表,而不会忽略多个空格
- 如何将列表从一个类复制到另一个类
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 在c++中为链接列表创建复制构造函数/函数
- 使用继承的指针列表复制构造函数或重载运算符=
- 构造函数初始值设定项列表未调用复制构造函数
- 如何在不复制列表的情况下将列表传递给线程,同时销毁原始列表
- 复制构造函数初始化初始化列表中的引用成员会导致指针悬空
- 将链接列表复制到linkedlist的引用
- C 单链接列表复制构造函数分割故障
- 双重列表复制构造函数:与单一列表复制构造函数有何不同
- 将带有指针的 STD 列表复制到另一个带有指针的 STD 列表
- C++列表:复制成员列表中的本地列表
- 如何通过赋值运算符重载将一个列表复制到另一个列表上?C++
- 将列表复制到C++中的地图
- c++ std 将列表复制到映射
- 链接列表复制构造函数和赋值操作符