The template template argument can't be deduced for both foo
and foo2
.
If I remove the sfinae part, the template template argument was successfully deduced for both foo
and foo2
.
How to fix either the span
class or foo
and foo2
?
Thanks.
Test (also at godbolt.org)
#include <type_traits>
template<typename T>
using enable_if_t_const = typename std::enable_if<
std::is_const<T>::value
>::type;
template<typename T, typename=void> class span;
template<typename T>
class span<T, enable_if_t_const<T>> {
public:
explicit span(const T* const data) {}
};
template <typename T, template<typename> class S>
void foo() {}
template <typename T, template<typename> class S>
void foo2(S<T>& s) {}
int main() {
int arr[] = {1};
span<const int> s(arr);
foo<const int, span>();
foo2(s);
return 0;
}
This is because, although you have a default template parameter, span
isn't a template <typename> class S
. It's a template <typename, typename> class S
.
The easiest fix is to change it to
template <typename T, template<typename...> class S>
void foo2(S<T>& s) {}
So that you can accept any S
that takes any number of types (although we only use it with one).