简体   繁体   中英

Failing to compile explicitly specialized template struct on g++/clang++ with std::enable_if

I've tried to compile this with msvc and it compiles fine. On the other hand I failed to compile it with g++ and clang++. Error I get is no type named 'type' in 'struct std::enable_if<false, void>' . How would I resolve this error?

#include <type_traits>

template <bool v>
struct a {

    template <typename T = typename std::enable_if<v>::type>
    void function();

};

template struct a<false>;
template struct a<true>;

template<bool v>
template<typename T>
void a<v>::function() { }

int main() {

}

I'm trying to make void function visible if passed bool template is true .

You are not using SFINAE correctly because the bool you pass to enable_if (which is v ) is not dependent on the function template parameters.

The canonical way to selectively add or remove members of a class template is to use template specialization. For example:

template <bool v>
struct a {
    void function();
};

template< >
struct a<false> {
};

Now, only a<true> will have the function member. If you have many common members that should be present in a regardless of v , you can move these members to a base class and derive both specializations from it:

struct a_common {
    void common_function();
};

template <bool v>
struct a : public a_common {
    void function();
};

template< >
struct a<false> : public a_common {
};

This can be achieved with SFINAE as well, but it will require a bit of a trick. As mentioned above, we need to make function a template, and we need to ensure that the condition used in enable_if depends on its template parameters. Since we don't have any template parameters, we need to add a dummy one:

template <bool v>
struct a {
    template<
        typename Dummy = void,
        typename = typename std::enable_if<
            std::is_same< Dummy, Dummy >::value && v
        >::type
    >
    void function();
};

Here, we use is_same trait to introduce a formal dependency on the Dummy template parameter when calculating the first template parameter of enable_if . Naturally, the result of is_same will be true , so effectively v decides whether the function template can be instantiated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM