我正在查看C++ 0x的计划,并std::initializer_list
在用户类中实现初始化列表.如果不使用它本身,或者使用一些"编译魔术",这个类就不能用C++实现.如果可以,则不需要它,因为您实现的任何技术initializer_list
都可用于在您自己的类中实现初始化列表.
还有哪些类需要某种形式的"编译魔术"才能工作?标准库中哪些类无法由第三方库实现?
编辑:也许不是实现,我应该说实例化.事实上,这个类与语言功能直接相关(你不能使用初始化列表initializer_list
).
与C#进行比较可能会清除我想知道的内容:IEnumerable和IDisposable实际上是硬编码为语言功能.我一直认为C++是免费的,因为Stroustrup试图让所有东西都可以在库中实现.那么,是否有任何其他类/类型与语言功能密不可分.
我唯一能想到的是typeid返回的type_info类.据我所知,VC++通过在编译时静态实例化所有需要的type_info类来实现这一点,然后根据vtable中的值在运行时简单地生成一个指针.这些是可以使用C代码完成的事情,但不是符合标准或可移植的方式.
std::type_info
是一个简单的类,虽然填充它需要typeinfo
:编译器构造.
同样,异常是普通对象,但抛出异常需要编译器魔术(分配的异常在哪里?).
对我来说,问题是"如果std::initializer_list
没有编译魔术,我们能接近多少?"
查看维基百科,std::initializer_list
可以通过看起来很像数组文字的东西进行初始化.让我们尝试给出std::initializer_list
一个带有数组的转换构造函数(即一个带有单个参数的构造函数T[]
):
namespace std { templateclass initializer_list { T internal_array[]; public: initializer_list(T other_array[]) : internal_array(other_array) { }; // ... other methods needed to actually access internal_array } }
同样,一个使用a的类std::initializer_list
通过声明一个带有单个std::initializer_list
参数的构造函数 - 也就是转换构造函数:
struct my_class { ... my_class(std::initializer_list) ... }
所以行:
my_class m = {1, 2, 3};
让编译器思考:"我需要调用一个构造函数my_class
; my_class
有一个构造函数需要一个std::initializer_list
;我有一个int[]
文字;我可以将一个转换int[]
为一个std::initializer_list
;我可以将它传递给my_class
构造函数"(请阅读到最后在告诉我C++不允许链接两个隐式的用户定义转换之前的答案.
那么这有多接近?首先,我缺少初始化列表的一些功能/限制.我没有强制执行的一件事是初始化列表只能用数组文字构造,而我initializer_list
也接受已经创建的数组:
int arry[] = {1, 2, 3}; my_class = arry;
另外,我没有打扰rvalue引用.
最后,如果编译器隐式地将两个用户定义的转换链接在一起,则此类仅适用于新标准.这在正常情况下是特别禁止的,因此该示例仍然需要编译魔术.但我认为(1)类本身是一个普通类,(2)涉及的魔法(强制执行"数组文字"初始化语法并允许两个用户定义的转换被隐式链接)比它看起来要少乍一看.