不使用自己,或者使用一些“编译器魔术”.如果可以的话,这不是必需的,因为用于实现initializer_list的任何技术都可以用于在你自己的类中实现初始化器列表.
什么其他类需要某种形式的“编译器魔术”工作?标准库中哪些类别无法由第三方库实现?
编辑:可能而不是实现,我应该说实例化.更重要的是,这个类与语言特性直接相关(不能使用initializer_list的初始化器列表).
与C#的比较可能会清除我所想知道的:IEnumerable和IDisposable实际上是硬编码为语言特性.我一直认为C是免费的,因为Stroustrup试图在图书馆中实现一切.那么,是否有任何其他类/类型与语言功能密不可分.
解决方法
同样,异常是普通对象,但抛出异常则需要编译器魔术(分配了哪些异常?).
对我来说,这个问题是“我们几乎可以到没有编译器魔术的std :: initializer_lists?
查看wikipedia,std :: initializer_list< typename T>可以通过看起来很像数组文字的东西进行初始化.我们尝试给我们的std :: initializer_list< typename T>一个接受数组的转换构造函数(即,一个构造函数,它接受T []的单个参数):
namespace std { template<typename T> class initializer_list { T internal_array[]; public: initializer_list(T other_array[]) : internal_array(other_array) { }; // ... other methods needed to actually access internal_array } }
同样,使用std :: initializer_list的类也是通过声明一个构造函数来构造一个单一的std :: initializer_list参数 – a.k.a.一个转换构造函数:
struct my_class { ... my_class(std::initializer_list<int>) ... }
所以行:
my_class m = {1,2,3};
导致编译器认为:“我需要调用my_class的构造函数; my_class有一个构造函数,它接受一个std :: initializer_list< int&;;我有一个int []文字;我可以将int []转换为std: :initializer_list< int&;;我可以将它传递给my_class构造函数“(请阅读答案的结尾,然后告诉我C不允许两个隐含的用户定义的转换被链接). 那么这么近呢?首先,我缺少初始化器列表的一些功能/限制.我不执行的一件事是,初始化器列表只能用数组文字构建,而我的initializer_list也可以接受一个已经创建的数组:
int arry[] = {1,3}; my_class = arry;
另外,我没有打扰到rvalue引用.
最后,这个类只适用于新的标准,如果编译器将两个用户定义的转换结合在一起,就应该这样做.这是在正常情况下特别禁止的,所以示例仍然需要编译器魔术.但我会认为(1)类本身是一个普通的类,(2)涉及到的魔法(执行“数组文字”初始化语法并允许两个用户定义的转换被隐式链接)不如它似乎乍一看.