首先让我解释一下“神奇”的含义。我将使用Java中的两个示例:
Object
类。+
对象定义了String
运算符。这意味着无法在纯(*)Java中实现Object
和String
类。现在这就是我对“魔术”的意思:要实现这些类,你需要编译器的一些特殊支持。
我一直喜欢的C ++是,据我所知,STL中没有这样的“神奇”,即可以用纯C ++实现STL。
现在我的问题是:这是真的吗?或者是否有部分STL无法在纯C ++中实现并需要一些“魔术”/特殊编译器支持?
(*)“纯”是指不使用任何类库。
答案 0 :(得分:52)
换句话说,有没有对编译器做过任何事情以允许STL需要工作的“特殊情况”?
没有
使用模板的魔力将它们全部实现为“纯粹的”C ++代码。
编译器已经做了一些工作来改进STL(我正在考虑各种优化)但是否则,如果你真的想要,你可以编写整个STL。有些人做过 - STLPort是一个没有任何编译器制造商支持的实现。
答案 1 :(得分:40)
就像gbjbaanb正确地说的那样,STL可以用普通的C ++实现,而不依赖于任何类型的编译器“魔术”。
但是,如果你要深入研究编译器的STL源代码,你可能会看到代码不是标准代码,也不是你自己不应该写的代码。
STL可以完全用标准C ++实现,但这并不意味着不允许编译器编写者偶尔使用编译器特定的扩展来改进它。例如,他们可能会插入非标准代码以确保更好的错误消息,或者可能解决其编译器中的某些缺陷,或者通过使用特定编译器的额外功能来启用特殊优化。
他们也一直使用您不允许使用的名称。例如,模板参数通常被命名为_Type
,因为它以下划线后跟大写字母开头,为实现保留。允许标准库使用它们,但你和我不是。因此,如果您要编写自己的STL实现,则必须进行一些小的更改,但这不是因为任何魔法,只是一种避免标准库和用户代码之间的名称冲突的方法。
答案 2 :(得分:15)
正如其他人所说,STL可以在纯标准C ++ 98中实现。没有说的是STL的开发与C ++模板机制的开发同时进行,并且在很大程度上推动了某些特性的包含。我相信Argument Dependent Lookup (ADL, aka Koenig Lookup),模板模板参数和默认模板参数都来到C ++来为Stepanov的STL开发服务。
因此,对于STL,他们将魔法转化为语言本身。很高兴标准委员会认识到,如果这些功能对于标准库有用,那么它们对我们其他人也可能有用!
答案 3 :(得分:14)
如果STL只表示C ++标准库的模板部分,那么完全可以实现它而没有任何“魔法”。每个给定的实现是否实际使用任何“魔法”都是一个不同的问题(STL中有部分“魔法”会有所帮助,但并非绝对必要)。
现在,如果你在谈论整个C ++标准库,那么它确实有一些“魔力”。典型的例子是库提供的::operator new
和::operator delete
实现。我们经常将它们称为日常语言中的“超载”,而形式上它们是可替换的。 C ++语言不向用户提供此类功能。用户无法编写可替换的功能。
另一个例子是offsetof
宏(继承自C标准库)。虽然它通常以“纯C”实现,但从迂腐的角度来看,流行的实现实际上是非法的(导致未定义的行为)。我还没有看到offsetof
的任何正式合法实施,所以我不确定它们是否可能。
另一个例子是(再次,从C继承)用于处理变量参数的宏。它们显然不能用纯C或C ++实现。
答案 4 :(得分:10)
我很确定某些type_traits
需要编译器魔法,例如has_trivial_constructor
,has_virtual_destructor
或is_pod
。
答案 5 :(得分:6)
std::initializer_list
需要编译器支持,不能重新实现为另一个类(据我所知),虽然我不确定它是否重要,因为它在c ++ 0x中。
答案 6 :(得分:5)
C ++ 0x将标准化一些事实上的“魔法”类型特征。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2984.htm
“C ++ 0x的附加类型特征”
这包含一些评论,例如“XXXX被认为需要编译器支持。”
另见
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Type-Traits.html#Type-Traits
http://msdn.microsoft.com/en-us/library/ms177194(v=vs.80).aspx
答案 7 :(得分:2)
正如“gbjbaanb”正确地说,STL的实施没有任何魔力。它是用纯C ++编写的。您可以自己实现它,但已经可以作为库使用,以使您的生活更简单。
答案 8 :(得分:-2)
STL是标准(标准模板库)。该标准规定了STL实现的要求。从使用的角度来看,没有“魔力”,没有特殊的依赖关系你需要照顾。它可以在这些编译器支持的所有平台上的任何主要C ++编译器上使用。