Background
As per [temp.arg.template]/1,
A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression.
which means that it is not possible to pass a function template as a default template template argument.
As expected, the following code snippet:
template <typename>
void func() {}
template <template <typename> typename Wrapper = decltype(&func)>
struct Foo {};
results in the error below (Clang):
error: default template argument for a template template parameter must be a class template
template <template <typename> typename Wrapper = decltype(&func)>
Problem
However, when a function template is provided as a default template template argument constrained by concept, this raises a different error:
void placeholder() {}
void func(std::invocable auto f) {}
template <typename Fn, typename FnArg>
concept FooConcept = std::is_invocable_v<FnArg>;
template <FooConcept<decltype(&placeholder)> Wrapper = decltype(&func)>
struct Foo {};
This, surprisingly, yields an overloaded error:
Clangerror: reference to overloaded function could not be resolved; did you mean to call it?
template <FooConcept<decltype(&placeholder)> Wrapper = decltype(&func)>
GCC
error: 'decltype' cannot resolve address of overloaded function
99 | template <FooConcept<decltype(&placeholder)> Wrapper = decltype(&func)>
When decltype(&func)
is replaced with a functor, which is a class template,
void placeholder() {}
template <typename Fn, typename FnArg>
concept FooConcept = std::is_invocable_v<FnArg>;
struct Functor {
auto operator()(std::invocable auto f) -> void {}
};
template <FooConcept<decltype(&placeholder)> Wrapper = Functor>
struct Foo {};
This compiles without an error.
Question
- Is this derived from the error in Background but showing a different message?
- If not, how come it shows an error related to an overloaded function?