0

I want to write a template class with two template parameters, where one implementation of a method is available when the parameter types are the same, and a different implementation when the types are different.

I know I can do this with template specialization:

template<typename T, typename W> class MyClass {
public:
  void myMethod() { std::cout << typeid(T).name() << " != " << typeid(W).name() << std::endl; }
};
template<typename T> class MyClass<T,T> {
public:
  void myMethod() { std::cout << typeid(T).name() << " = " << typeid(T).name() << std::endl; }
};

But I was trying to get better at SFINAE paradigms, and so tried writing something like this:

template<typename T, typename W> class MyClass {
public:
    template<typename T_ = T, typename W_ = W,
            typename = std::enable_if_t<std::is_same_v<T_,W_>>> void myMethod() {
                std::cout << typeid(T_).name() << " = " << typeid(W_).name() << std::endl;
            }

    template<typename T_ = T, typename W_ = W,
            typename = std::enable_if_t<!std::is_same_v<T_,W_>>> void myMethod() {
                std::cout << typeid(T_).name() << " != " << typeid(W_).name() << std::endl;
            }
};

But the compiler says that this is redeclaration of the method.

Can someone correct my usage of SFINAE here?

Thanks!

Mat
  • 202,337
  • 40
  • 393
  • 406
user1488777
  • 125
  • 4
  • Sfinae is ok, but the methods are really the same. They have same number of parameters of the same types. – Zereges Mar 05 '20 at 11:46
  • So are you saying that SFINAE can't be used to do what I'm describing? Is its usage really about hiding methods that are distinct but invalid for certain types, rather than providing different implementations of the same method to different types? I am happy to stick with my template specialization if that's the right way to solve this problem – user1488777 Mar 05 '20 at 11:54
  • @user1488777 - SFINAE can be used, it's just nuanced. Refer to the duplicate questions for both a workaround and an explanation. – StoryTeller - Unslander Monica Mar 05 '20 at 11:55
  • Fwiw, since you are already using C++17 it might be much simpler to implement this within `myMethod` simply with `if constexpr (std:is_same_v) { /* ... */ } else { /* ... */ }`. – jdehesa Mar 05 '20 at 12:00

0 Answers0