mardi 4 juin 2019

How to make SFINAE work with template specializations?

I have a template method foo. I would like to have several different implementations: for T, vector<T> and vector<vector<T>> where T is a built-in type or some complex class. I would like to use SFINAE to separate implementations for built-in types and classes and restrict a set of allowable types.

The following code works correctly but I get warning messages:

" 8:37: warning: inline function 'constexpr bool isType() [with T = std::vector]' used but never defined

8:37: warning: inline function 'constexpr bool isType() [with T = std::vector >]' used but never defined "

#include <type_traits>
#include <vector>

using namespace std;

class ComplexClass{};

template<typename T> constexpr bool isType();
template<> constexpr bool isType<int>()  {return true;}
template<> constexpr bool isType<ComplexClass>() {return false;}

template <typename T>
inline typename enable_if<isType<T>(), void>::type
foo(T& value) {}

template <typename T>
inline typename enable_if<!isType<T>(), void>::type
foo(T& value) {}

template <typename T>
inline typename enable_if<isType<T>(), void>::type
foo(vector<T>& value) {}

template <typename T>
inline typename enable_if<isType<T>(), void>::type
foo(vector<vector<T>>& value) {}

int main()
{
    int a;
    vector<int> b;
    vector<vector<int>> c;
    ComplexClass d;
    char e;
    foo(a);
    foo(b);
    foo(c);
    foo(d);
//    foo(e); // has to lead to an error
    return 0;
}

It looks like compiler tries to pass vector<...> into the first enable_if method and fails. But it would be great to skip such methods because we have better candidates for vector<T> and vector<vector<T>>. Is it possible to do?

Aucun commentaire:

Enregistrer un commentaire