2

我是 cplusplus 的新手,感谢您回答我的问题。

stl_list.h 中的段落内容如下:

// NOTA BENE
// The stored instance is not actually of "allocator_type"'s
// type.  Instead we rebind the type to
// Allocator<List_node<Tp>>, which according to [20.1.5]/4
// should probably be the same.  List_node<Tp> is not the same
// size as Tp (it's two pointers larger), and specializations on
// Tp may go unused because List_node<Tp> is being bound
// instead.
//
// We put this to the test in the constructors and in
// get_allocator, where we use conversions between
// allocator_type and _Node_alloc_type. The conversion is
// required by table 32 in [20.1.5].
  1. 我在哪里可以找到 [20.1.5]/4 和 table 32 这样的东西?
  2. 为什么 Tp 上的专业化可能会被闲置?这实际上意味着什么?(如果您能提供一段简单的源代码和简单的解释,我将不胜感激。)
  3. 如果人们确实需要专业化怎么办,有没有办法破解它??:)
4

3 回答 3

3
  1. 正如 Paul 已经指出的,这些是对 C++ 标准的引用。(尽管他发布的链接侵犯了版权,并且是该标准的旧副本)您在此处阅读了如下参考:

    N3376 23.2.1 [container.requirements.general]/6
    ^^^^^ Version of the standard working paper being discussed
          ^^^^^^ Clause / subclause in the standard being discussed
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ section name
                              paragraph number    ^
    

    您会在标准参考中看到打印在 s 中的部分标题的原因[]是因为该标准的不同工作文件副本会根据条款编号移动部分,但部分标题相对恒定。(例如,如果有人使用比 N3376 更晚的标准工作文件,他们可以搜索[container.requirements.general]并找到我正在谈论的部分)
    段落编号单独列出以将其与子条款编号区分开来。例如,是23.2.1第 23.2 条中的第 1 段还是整个子条23.2.1?将其分开可以更清楚地说明这一点。

  2. 这意味着如果您为分配器类创建模板特化,则针对给定类型的模板特化可能不会被使用;并改为使用主模板。这是因为分配器的特化是基于类型的。假设您有一个主模板my_allocator<Type>和一个专门my_allocator<int>针对int. 但是std::list是链表,所以需要分配list_node<int>对象,而不是ints。所以它创建了一个my_allocator<list_node<int>>替代,这使得<int>未使用的专业化。有关更多示例和细节,
    请参阅Stephan T. Lavavej 的优秀系列 Core C++,第 5 部分“模板专业化” 。

  3. 你不能;至少不是以标准方式。list用于其列表节点的内部名称由实现定义。您不能在可移植代码中命名该类型以进行专业化。

于 2012-12-01T08:16:15.460 回答
2

至于你的问题1:

它似乎是对与分配器要求相关的 ISO C++ 标准的引用。我在这里找到了 1998 年 C++ 标准的副本:

http://www-d0.fnal.gov/~dladams/cxx_standard.pdf

看看 pdf 中的第 354 页(第 380 页)。表 32 出现了 2 页。

至于你的问题 2 和 3,那远高于我的工资等级。我可能会冒昧地说,专业化是指从 Tp 派生的类。但我只是不确定。

于 2012-12-01T06:55:34.277 回答
1

对于std::list类型,它将(通常)使用类似node(或类似的东西)的类来保存类型的值Tp以及指向前一个和下一个元素的指针。显然,当您使用分配器来创建这些值时,实际上需要的不是一个类型,Tp而是一个类型node<Tp>。这就是他们需要重新绑定分配器的原因。因此,在列表类中,您会看到类似std::allocator<Tp>::template rebind<node<Tp>>.

专业化可能未使用的原因是它在内部分配node<Tp>而不是Tp. 因此,如果我们编写自己的分配器类,然后将其专门用于Tp,则这种专门化将不会用于std::list。例如:

template <typename T>
class my_allocator
{
     //typedefs
     pointer allocate(...);
     void deallocate(...);

     //Other member functions
};

template <>
class my_allocator<int>
{
     //Some specialization for int
     ...

};

现在,如果我们使用std::list<int, my_allocator<int>>,由于分配器会反弹,我们最终可能my_allocator<node<int>>会使用非专业化的,因此将使用非专业化版本my_allocator

如果std::liststd::list.

于 2012-12-01T08:17:04.123 回答