no type named ‘type’ in ‘struct std::enable_if<false, void>

Mochan picture Mochan · May 13, 2019 · Viewed 10.5k times · Source

Why does this not work?

It is giving me an error

error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
     using enable_if_t = typename enable_if<_Cond, _Tp>::type;

It I don't put getX() and getY() inside struct B it works. However, if I put them both inside a struct then it doesn't.

#include <iostream>
#include <boost/type_traits/has_dereference.hpp>

struct A {
    A(int i) : x(i) {}
    int x;
};

template<typename T>
struct B {
    template<typename std::enable_if_t<!boost::has_dereference<T>::value> * = nullptr>
    auto getX(T t) {
        return t.x;
    }

    template<typename std::enable_if_t<boost::has_dereference<T>::value> * = nullptr>
    auto getX(T t) {
        return t->x;
    }
};

int main()
{
    A a{4};

    B<A> g;

    std::cout << g.getX(a) << std::endl;

    return 0;
}

But, this works fine.

struct B {
    template<typename T, typename std::enable_if_t<!boost::has_dereference<T>::value> * = nullptr>
    auto getX(T t) {
        return t.x;
    }

    template<typename T, typename std::enable_if_t<boost::has_dereference<T>::value> * = nullptr>
    auto getX(T t) {
        return t->x;
    }
};

Solution

This seems to work:

template<typename T1>
struct B {
    template<typename T = T1, typename std::enable_if_t<!boost::has_dereference<T>::value> * = nullptr>
    auto getX(T t) {
        return t.x;
    }

    template<typename T = T1, typename std::enable_if_t<boost::has_dereference<T>::value> * = nullptr>
    auto getX(T t) {
        return t->x;
    }
};

Answer