Home > Software engineering >  Why SFINAE report error in function overloading
Why SFINAE report error in function overloading

Time:03-02

Follwing code can't compile,I just want testing SFINAE,why it can't compile?

#include <type_traits>
template<typename T>
class TestVoid {
    template<std::enable_if_t<std::is_void_v<T>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<std::enable_if_t<!std::is_void_v<T>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};

int main() {
    TestVoid<void> t;
    return 0;
}

CodePudding user response:

The problem is the conditions of std::enable_if don't depend on template parameter of func themselves.

You might change the code to

template<typename T>
struct TestVoid {
    template<typename X = T, std::enable_if_t<std::is_void_v<X>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<typename X = T, std::enable_if_t<!std::is_void_v<X>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};

LIVE

CodePudding user response:

When you instantiate the class template, all of the member function declarations must be valid. In your case, one of them won't be. Instead, you can delegate func to another function template.

live link

template<typename T, std::enable_if_t<std::is_void_v<T>> * = nullptr>
void func() {
    std::cout << "void\n";
}

template<typename T, std::enable_if_t<!std::is_void_v<T>> * = nullptr>
void func() {
    std::cout << "none void\n";
}

template<typename T>
class TestVoid {
  public:
    void func_member() {
        func<T>();
    }
};

Or, if you want to keep the actual implementation of func as a member function:

live link

template<typename T>
class TestVoid {
  public:
    void func_member() {
        func<T>();
    }
  private:
    template<typename U, std::enable_if_t<std::is_void_v<U>> * = nullptr>
    void func() {
        std::cout << "void\n";
    }

    template<typename U, std::enable_if_t<!std::is_void_v<U>> * = nullptr>
    void func() {
        std::cout << "none void\n";
    }
};
  • Related