Question

I am trying to use the boost::enable_if to turn on/off some functions in the class template but always get the compilation error error: no type named "type" in struct boost::enable_if.

My snippet:

#include <iostream>
#include <tr1/type_traits>
#include <boost/utility.hpp>

namespace std {
    using namespace tr1;
}

template <typename T1>
struct C {
    template< typename T2 >
    void test( T2&, typename boost::enable_if<
    std::is_const< T1 >, T1 >::type* = 0 ) {

        std::cout << "const" << std::endl;
    }

    template< typename T2 >
    void test( T2&, typename boost::disable_if<
    std::is_const< T1 >, T1 >::type* = 0 ) {

        std::cout << "non-const" << std::endl;
    }
};

int main() {
    const int ci = 5;
    int i = 6;

    C<char> c;
    c.test(ci);
    c.test(i);
    return 0;
}

But the following similar codes work fine:

#include <iostream>
#include <tr1/type_traits>
#include <boost/utility.hpp>

namespace std {
    using namespace tr1;
}

template <typename T1>
struct C {
    template< typename T2 >
    void test( T2&, typename boost::enable_if<
    std::is_const< T2 >, T1 >::type* = 0 ) {

        std::cout << "const" << std::endl;
    }

    template< typename T2 >
    void test( T2&, typename boost::disable_if<
    std::is_const< T2 >, T1 >::type* = 0 ) {

        std::cout << "non-const" << std::endl;
    }
};

int main() {
    const int ci = 5;
    int i = 6;

    C<char> c;
    c.test(ci);
    c.test(i);
    return 0;
}

What I want to achieve is to disable/enable some member functions based the types declared in the class template. Actually the template member function is not needed. They're only added for SFINAE.

Anyone can help??

Thanks!

No correct solution

OTHER TIPS

SFINAE (which the mechanism used to implement enable_if) only works in context of the function template's template parameters. In your case, T1 is a template parameter of the enclosing class template, not of the function template itself. From the function template's point of view, it's a fixed type and not being able to use it the way it's spelled out in the declaration is a normal error, not a substitution failure.

One way would be a specialization of the class itself, possibly as a base class in case you only want to do this for some functions:

template <typename T1>
struct B {
    template<typename T2>
    void test( T2& ) {

        std::cout << "non-const" << std::endl;
    }
};

template <typename T1>
struct B< const T1 > {
    template<typename T2>
    void test( T2& ) {

        std::cout << "const" << std::endl;
    }
};

template <typename T1>
struct C : B<T1> {
    //...
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top