I have discovered that the minimal example below works on gcc and clang and even Visual Studio but it does not compile with icc. I am trying to determine whether or not this is valid C++, but I am not able to find the relevant parts of the standard that answer my question since this is several different concepts combined.
// struct with multiple template parameters
template<typename A, typename B = int>
struct C
{
};
// struct that tries to use C's default second parameter without specifying it
template<typename D, template<typename E, typename ...> class F>
struct G
{
F<D> h;
};
int main()
{
G<char, C> i;
}
With icc (16.0.3), compilation gives the following error:
struct.cpp(12): error: too few arguments for template template parameter "F"
F<D> h;
detected during instantiation of class "G<D, F> [with D=char, F=C]" at line 17
Is this valid C++?
To me it seems like it should be, because C
has a default value for its second template parameter, meaning that F<D>
with F = C
should be a valid construction.
I believe this is a gcc/clang bug. This is related to the [still-open] CWG Issue 150. The rationale provided includes:
Default arguments are allowed for the parameters of a template template parameter, and those default arguments alone will be considered in a specialization of the template template parameter within a template definition; any default arguments for the parameters of a template template argument are ignored.
The template template parameter F
doesn't have any default arguments - and the default arguments for C
are ignored. So we should end up with an ill-formed specialization, as ICC suggests.
In the examples provided in the issue, both gcc and clang seem to implement the rule (neither allows the call to f()
and both go through the operator float()
path in Mark Mitchell's example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With