代码之家  ›  专栏  ›  技术社区  ›  Johannes Schaub - litb

具有其他可选模板参数的标准库容器?

  •  24
  • Johannes Schaub - litb  · 技术社区  · 16 年前

    在文章中多次阅读该声明之后——我想将此问题添加到Stackoverflow中,并询问社区——以下代码是否可移植?

    template<template<typename T, typename Alloc> class C>
    void f() {
      /* some code goes here ... */
    }
    
    int main() {
      f<std::vector>();
    }
    

    是提供的实现 std::vector 除了两个众所周知的模板参数之外,真的允许有其他默认模板参数吗?这将导致上述代码格式错误,因为它假定有两个模板参数。见最后一段 in this article 请举例说明这一主张。

    4 回复  |  直到 16 年前
        1
  •  23
  •   Johannes Schaub - litb    16 年前

    我发现如下 issue report ,上面说

    没有歧义;这个标准写得很清楚。不允许库实现者向标准库类添加模板参数。这不属于“似乎”规则的范畴,因此只有在标准明确允许实现者这样做的情况下,才允许这样做。这将需要改变标准。

    LWG决定不进行此更改,因为它将破坏涉及模板参数或标准库类模板专门化的用户代码。

    那些认为实现可能会添加其他可选参数的书籍和人士似乎是错误的。

        2
  •  2
  •   csj    16 年前

    令人难以置信的是,我最近正在阅读“C++模板:完整指南”,上一本书在第111页上标注了以下内容:

    模板参数必须是类模板,其参数必须与其替换的模板参数的参数完全匹配。模板参数的默认模板参数将被忽略(但如果模板参数具有默认参数,则在模板实例化过程中会考虑这些参数)。

    作为一个真实的测试,我在g++(成功)和Visual Studio 2008(在不匹配的参数上失败)中编译了以下内容:

    template<typename T1, typename T2, typename T3 = float>
    class MyClass
    {
    public:
        T1 v1;
        T2 v2;
        T3 v3;
    };
    
    template<template<typename T1, typename T2> class C>
    void f()
    {
        C<int,double> *c = new C<int,double>();
    }
    
    int main ()
    {
        f<MyClass>();
        return 0;
    }
    
        3
  •  1
  •   me22    16 年前

    检查第17.4.4节[库符合性]的子条款。

    17.4.4.3/3表示“实现不能将全局或非成员函数声明为采用其他默认参数”,但17.4.4.4/2明确允许使用更长的成员函数签名替换所述的成员函数签名,只要其他参数具有默认值。

    但是,没有关于模板的章节,因此,如果他们觉得有必要提供17.4.4.3/3,在我看来,额外的模板参数是允许的,除非措辞相反。

        4
  •  0
  •   Johann Gerell    15 年前

    我也看到过这种说法。但是

    首先,我从未见过这样的实现。我似乎记得Andrei Alexandrescu曾经考虑过在类固醇上使用分配器类型(比如 my_fancy_thing<std::allocator,more_info_to_pass_to_the_container> ,而 std::allocator 也仍然有效)。但即使这样,也能保持你的信心 f() 工作,这是最接近于一个实现打破你的例子,我所听过的讨论。

    我认为这与a 0 指针不一定要用一个所有位都设置为零的值来表示——即使供应商真的有这种自由(我不知道,因为双方都有声明),他们也不会使用它,因为这会破坏所有现有的代码。