R zu
R zu

Reputation: 2074

template template argument deduction with sfinae

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

Upvotes: 3

Views: 83

Answers (1)

Justin
Justin

Reputation: 25387

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).

Demo

Upvotes: 4

Related Questions