Search code examples
c++sfinae

Why SFINAE report error in function overloading


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;
}

Solution

  • 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";
        }
    };