Standard Library Containers with additional optional template parameters?

Having read the claim multiple times in articles - I want to add this question to Stackoverflow, and ask the community - is the following code portable?

template<template<typename T, typename Alloc> class C>
void f() {
  /* some code goes here ... */
}

int main() {
  f<std::vector>();
}

Is the implementation that supplies std::vector really allowed to have additional, defaulted template parameters beyond the two well known ones? This would render the above code ill-formed, as it assumes two template parameters. See the last paragraph in this article for an example of such a claim.


I found the following issue report, which says

There is no ambiguity; the standard is clear as written. Library implementors are not permitted to add template parameters to standard library classes. This does not fall under the "as if" rule, so it would be permitted only if the standard gave explicit license for implementors to do this. This would require a change in the standard.

The LWG decided against making this change, because it would break user code involving template template parameters or specializations of standard library class templates.

The books and people that say an implementation may add other optional parameters seem to be wrong.


Incredibly, I was recently reading "C++ Templates: The Complete Guide," and last book marked the following on page 111:

A template template argument must be a class template with parameters that exactly match the parameters of the template template parameter it substitutes. Default template arguments of a template template argument are ignored (but if the template template parameter has default arguments, they are considered during the instantiation of the template).

So, if the book is to be believe, your example where non-standard default parameters are added to std::vector would be legal - since default template arguments of a template template argument are ignored.

As a real world test, I compiled the following in g++ (successfully) and Visual Studio 2008 (failed on the mismatched parameters):

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;
}

Check subsubsections of 17.4.4 [lib.conforming].

17.4.4.3/3 says that "a global or non-member function cannot be declared by the implementation as taking additional default arguments", but 17.4.4.4/2 explicitly allows replacing described member function signatures with longer ones so long as the additional parameters have defaults.

There's no section for templates, though, so if they felt the need to provide 17.4.4.3/3, it seems to me like extra template parameters are allowable barring wording to the contrary.