1
template <typename T,  typename = enable_if_t<is_same<T, int>::value>>
void qw(T t) 
{
  std::cout << "int " << endl;
}

template <typename T , typename =  enable_if_t<is_same<T, float>::value>>
void qw(T t) 
{
   cout << "float" << endl;
}

// Invoked from main as 
int main()
{
   int x = 10;
   qw(x);
}

The error I get with g++9.2

sp.cc:153:6: error: redefinition of ‘template<class T, class> void qw(T)’
  153 | void qw(T t)
      |      ^~
sp.cc:147:6: note: ‘template<class T, class> void qw(T)’ previously declared here
  147 | void qw(T t)

I would assume only one overload is well formed and will be selected. However it complains of multiple definitions. Can someone help explain why ?

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
user3882729
  • 1,339
  • 8
  • 11

1 Answers1

3

From cppreference, which has this very example as a Note:

A common mistake is to declare two function templates that differ only in their default template arguments. This does not work because the declarations are treated as redeclarations of the same function template (default template arguments are not accounted for in function template equivalence).

So what you need to do is not make the sfinae'd type a default argument. Instead, you could make it resolve to some type, e.g. int, and give it a default value, like this:

template <typename T, enable_if_t<is_same_v<T, int>, int> = 0>
void qw(T t)  
{
  std::cout << "int " << endl;
}

template <typename T, enable_if_t<is_same_v<T, float>, int> = 0>
void qw(T t) 
{
   cout << "float" << endl;
}
cigien
  • 57,834
  • 11
  • 73
  • 112
  • The above does work fine. Just to get a better understanding, in this case aren't we also re-defining the template with only the default *value* being different, i.e. both have the same second template parameter as ```int``` with one of them being SFINAE'd out ? – user3882729 Dec 05 '21 at 22:44
  • @user3882729 See [this answer](https://stackoverflow.com/a/70351468), and also https://stackoverflow.com/questions/36499008 – cigien Dec 14 '21 at 16:35