The following code compiles fine with g++, but not with clang++ (3.6):
// Forward declaration:
template <class S, class T>
struct Base;
template <class T>
struct BaseFriend {
friend struct Base<int, T>;
};
// Actual declaration:
template <class S, class T = int>
struct Base {
void foo() {}
};
struct DerivedFriend : BaseFriend<int> {};
struct Derived : Base<int> {
void foo(int) {
Base<int>::foo();
}
};
Error occurs in the Derived::foo
definition:
error: too few template arguments for class template 'Base'
Base<int>::foo();
^
test.cpp:3:8: note: template is declared here
struct Base;
^
Error goes away after few minor fixes, like:
DerivedFriend
is not used.But, what is wrong with the original code?
Default template arguments Default template arguments are specified in the parameter lists after the = sign. Defaults can be specified for any kind of template parameter (type, non-type, or template), but not to parameter packs.
If the default is specified for a template parameter of a primary class template , primary variable template, (since C++14)or alias template, each subsequent template parameter must have a default argument, except the very last one may be a template parameter pack.
(C++11) Every template is parameterized by one or more template parameters, indicated in the parameter-list of the template declaration syntax: Each parameter in parameter-list may be: a template template parameter. 1) A non-type template parameter with an optional name. 2) A non-type template parameter with an optional name and a default value.
Each function template has a single function parameter whose type is a specialization of X with template arguments corresponding to the template parameters from the respective function template where, for each template parameter PP in the template parameter list of the function template, a corresponding template argument AA is formed.
Definitely a clang bug, looks like #10147. The standard clearly allows this [temp.param]/10:
The set of default template-arguments available for use with a template declaration or definition is obtained by merging the default arguments from the definition (if in scope) and all declarations in scope in the same way default function arguments are (8.3.6). [ Example:
template<class T1, class T2 = int> class A; template<class T1 = int, class T2> class A;
is equivalent to
template<class T1 = int, class T2 = int> class A;
—end 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