stl_list.h中“NOTA BENE”的段落是什么意思?

时间:2012-12-01 06:29:14

标签: c++

我是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和表32这样的东西?
  2. 为什么Tp的专业化可能会被闲置?这究竟意味着什么? (如果你能提供一段简单的源代码和一个简单的解释,我真的很感激。)
  3. 如果人们确实需要专业化,有没有办法破解它?:)

3 个答案:

答案 0 :(得分:2)

关于你的问题1:

它似乎是对ISO C ++标准的引用,涉及分配器要求。我发现了一个 这里是1998 C ++标准的副本:

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

查看pdf中的页面354(第380页)。表32显示2页。

关于你的问题2&amp; 3,这远高于我的工资等级。我可能会冒险通过专业化来表示从Tp派生的类。但我当然不知道。

答案 1 :(得分:2)

  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    ^
    

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

  2. 这意味着如果为allocator类创建模板特化,则针对给定类型的模板特化可能会被取消使用;并使用主模板。这是因为分配器的特化基于类型。假设您有一个主要模板my_allocator<Type>my_allocator<int>的专门化,它为int执行了一些特殊操作。但是std::list是一个链表,因此它需要分配list_node<int>个对象,而不是int个。因此,它会创建一个my_allocator<list_node<int>>,这会使<int>的特化未使用。
    有关更多示例和详细信息,请参阅Stephan T. Lavavej's excellent series, Core C++, part 5 of n "Template Specializations"

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

答案 2 :(得分:1)

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

专业化可能未被使用的原因是内部分配node<Tp>而不是Tp。因此,如果我们编写自己的allocator类,然后将其专门化为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::list之类的东西需要这样的特化,你可以通过专注于类似std::list类的内部节点来破解它,但这几乎肯定是不可移植的,我建议反对它。