c++ - initializer_list、构造函数和支撑初始化

标签 c++ c++11

在阅读不同类型的初始化时,我偶然发现了 std::initializer_list 的众多奇怪交互之一。 (上一篇文章 here)。这显然是一个简单的主题,是 C++ 书中最先出现的主题之一 std::vector .

关键是,如果你有一个构造函数接受一个(我猜只是)std::initializer_list ,当你用大括号初始化这个构造函数时,强烈推荐:换句话说,std::vector<int> NewVect{5, 10}将创建一个包含 5 和 10 的对象,而不是将 5 元素初始化为 10 ( std::vector<int> NewVect(5, 10) )。

auto 发生特殊行为大括号初始化( auto A={1,2,3} 将被推断为 std::initializer_list<int> )。现在,我无法相信 C++ 会针对特定对象进行特定处理,因为据我所知, header 只是编写良好且有用的代码片段。此外,如果您不直接或间接地使用这些语法,这些语法将不起作用 #include <initializer_list> ,即使我的编译器 VS2017 打印了一组非常特殊的错误,指出它需要该 header 才能工作(您可以使用 auto 轻松测试它)。

所以,我的问题是,假设此行为是来自启动器列表 header 的代码的效果,并且我的编译器可能是为假设使用 STD 而构建的,它是如何实现的?除了显式调用(即 std::vector<int> NewVect{5, 10} 等同于 std::vector<int> NewVect(5, 10) 而您现在需要调用 std::vector<int> NewVect{std::initializer_list<int>{5, 10}} ),我能否将此行为重新路由以使其永远不会发生?是否可以将此行为赋予其他用户构建的类?

最佳答案

given for granted that this behaviour is the effect of code from the initiliazer list's header and my compiler is probably built to assume the use of STD, how is it implemented?

标准中有一条特殊规则,内容大致如下:“如果您使用列表初始化 ({...}) 来构造对象,并且该对象有一个采用 std::initializer_list 的构造函数,选择该构造函数不考虑重载决议”。这意味着 std::initializer_list 构造函数在使用 {...} 初始化语法时始终优先于其他构造函数。


Could I reroute this behaviour to never happen aside from explicit call

在你的类中,你可以避免使用std::initializer_list。那么这种行为将永远不会发生。您不能为 std:: 类更改此设置。


Would be possible to give this behaviour to other, user-built classes?

不是你想要的语法,因为 std::initializer_list 是特殊的。您可以创建自己的 initializer_list 替代方案,或使用类似可变参数模板 构造函数的东西来强制用户使用显式语法。

关于c++ - initializer_list、构造函数和支撑初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53062794/

相关文章:

c++ - 如何在c++11中实现工厂+装饰器模式

c++ - 有人可以帮助这个程序中的错误吗?

c++ - 获取 typedef 结构数组中的行

c++ - CRTP派生类貌似不知道继承类型

c++ - std::transform 产生奇怪的输出

C++11 对 lambda 返回类型的限制

c++ - FizzBu​​zz.cpp 与 lambdas?

c++ - 为什么具有继承构造函数的类也会获得合成的默认构造函数?

c++ - 如何在构造函数中初始化struct的动态数组?

c++ - 读取文件并在 C++ 中拆分行