标准库容器与额外的可选模板参数?

在文章中多次阅读索赔 – 我想将此问题添加到Stackoverflow,并要求社区 – 是下面的代码可移植?

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

提供std::vector的实现是否真的允许超出两个众所周知的额外的默认模板参数? 这会使上面的代码格式不正确,因为它假定有两个模板参数。 有关这种索赔的示例,请参阅本文的最后一段。

我发现以下问题报告 ,其中说

没有歧义; 标准清晰如书面。 库实现者不允许向标准库类添加模板参数。 这不属于“似乎”的规定,所以只有当标准给予执行者明确的许可才能做到这一点。 这将需要改变标准。

LWG决定不进行这种更改,因为它会中断涉及模板模板参数或标准库类模板特化的用户代码。

说实现的书和人可能会添加其他可选参数似乎是错误的。

令人难以置信的是,最近我正在阅读“C ++模板:完整指南”,最后一本书在第111页标记为:

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

所以,如果这本书是相信的,你的例子非标准默认参数被添加到std :: vector将是合法的 – 因为模板模板参数的默认模板参数被忽略。

作为一个真实世界的testing,我编译了以下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; } 

检查17.4.4 [lib.conforming]的子子集。

17.4.4.3/3说“全局或非成员函数不能被实现声明为接受额外的默认参数”,但是17.4.4.4/2明确允许用更长的参数replace描述的成员函数签名,只要附加参数有默认值。

尽pipe如此,如果他们觉得有必要提供17.4.4.3/3,那么在我看来,额外的模板参数是可以允许的,除非相反。

我也看到了这个说法。 但。

首先,我从来没有看到这样做的实现。 我似乎记得Andrei Alexandrescu曾经考虑过在类my_fancy_thing<std::allocator,more_info_to_pass_to_the_container>上使用类似allocatortypes的东西(比如my_fancy_thing<std::allocator,more_info_to_pass_to_the_container> ,而std::allocator也会起作用)。 但即使如此,这仍然会让你的f()工作,这是一个违背我所听到过的例子的最接近的事情。

我认为这与下面的说法差不多:声明0指针不一定要用所有位设置为零的值表示 – 即使供应商真的有这种自由(我不知道,因为也有双方的要求),他们将永远不会使用它,因为这基本上会打破所有现有的代码。

所以我早就决定不用担心了。