构造函数和initializer_list
Constructor and initializer_list
谁能告诉我这背后的理论?
为什么最后一个调用不能编译?
测试。cc:在函数' int main() '中:测试。Cc:15:12:错误:' int ' [-fpermissive]的初始化式周围有太多大括号
错误:从"到"的无效转换[-fpermissive]测试。Cc:9:6:错误:初始化' void f(std::initializer_list) '的参数1 [-fpermissive] test.cc:15:12:
错误:聚合值在期望的整数中使用
我认为c++11或c++ 4.7在这一点上是坏的。谢谢你!
#include <initializer_list>
class A {
public:
A(const std::initializer_list<int>) {}
};
void f(const std::initializer_list<int>) {}
int main() {
A({1}); // Compile OK
f({1}); // Compile OK
A({{{1}}}); // Compile OK
//f({{{1}}}); // Compile Error.
}
我相信GCC是这么想的。
这是你的程序,有额外的一行,有趣的行编号。
int main() {
A({1}); // 1. Compile OK
f({1}); // 2. Compile OK
A{{1}}; // 3. Compile OK, equivalent to 1.
A({{{1}}}); // 4. Compile OK
//f({{{1}}}); // 5. Compile Error.
}
为什么GCC只编译4而不编译5?
为清楚起见,假设#4的结构实际上声明了一些东西:A a{{{1}}}; // 4a. Compile OK
GCC询问构造函数{{1}}
的参数是否为隐式转换为A
。所以是:
A{{1}}
从{{1}}
到A
的有效转换?3.
这个推理当然不适用于#5;因此错误。
如果您想阻止GCC接受#4,那么阻塞通过显式地启用构造函数来启用转换:
class A {
public:
explicit A(const std::initializer_list<int> il) {}
};
那么#4将给出错误:
error: converting to ‘A’ from initializer list would use explicit constructor ‘A::A(std::initializer_list<int>)’
A{1}可以初始化int类型。{{1}}可能不应该这样做——委员会对此有一个缺陷报告。GCC禁止这样做,而clang目前只是倾向于发出关于冗余大括号的警告。
当X是具有copy或move构造函数的类时,则X({…})可以调用其中一个构造函数。注意X{…}也可以,但限制为不允许用户定义转换(对于复制或移动构造函数)。
现在有了A({{{1}}}),第一个大括号被复制/移动构造函数所消耗。第二个递归到初始化列表。第三个是包含的int
根据标准,增加一个括号将打破A({{{{1}}}})。因为第二个大括号需要由a的复制/移动构造函数使用,但需要用户定义的转换序列。对于A{{{{1}}}}也是如此,因为这个原因它也是无效的。
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- GCC对可能有效的代码抛出init list生存期警告
- 使用std::list创建循环链表
- C2664 无法从'initializer list'转换参数
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 在C++中标记化"Braced Initializer List"样式字符串(使用 Boost?
- "默认参数":无法从'initializer list'转换为'std::initializer_list'
- 无法从'initializer-list'转换为用户控制器
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- 递归调用中出现错误"[Error] expression list treated as compound expression in initializer [-fpermissive]"
- VS2015无法从'initializer list'转换为'std::string'错误
- 编译器错误:"Non-aggregates cannot be initialized with initializer list."
- 无法转换...从 '<brace-enclosed initializer list>' 到 地图
- 无法将'<brace-enclosed initializer list>'转换为'double'作为回报
- <function-style-cast> 错误:无法从'initializer list'转换为'std::thread'
- initializer语言 - list不能转换为const margin *