1
template<typename T, typename = std::enable_if_t<std::is_trivially_copyable<T>::value>>
inline
int test_sfinae(T tc) {
    return 1;
}

template<typename T, typename = std::enable_if_t<!std::is_trivially_copyable<T>::value>>
inline
int test_sfinae(T ntc) {
    return 2;
}

Could someone explain to me why this code fails to compile and gives this error message:

C2995 'int test_sfinae(T)': function template has already been defined

I'm using MVSC.

Holt
  • 36,600
  • 7
  • 92
  • 139
Igor Mitrovic
  • 155
  • 1
  • 6
  • You might look as the note of [std::enable_if](http://en.cppreference.com/w/cpp/types/enable_if) which is similar to your error. – Jarod42 May 17 '18 at 13:45
  • Related to https://stackoverflow.com/questions/31152476/sfinae-duplicate-constructor-declaration and https://stackoverflow.com/questions/15427667/sfinae-working-in-return-type-but-not-as-template-parameter – Jarod42 May 17 '18 at 13:48

1 Answers1

8

Default template arguments do not participate in overload resolution, so your two declarations are actually identical.

You could rewrite the declaration as follow:

template <typename T, 
          std::enable_if_t<std::is_trivially_copyable<T>::value, int> = 0>
inline int test_sfinae(T tc) {
    return 1;
}

template <typename T, 
          std::enable_if_t<!std::is_trivially_copyable<T>::value, int> = 0>
inline int test_sfinae(T ntc) {
    return 2;
}

When T is trivially copyable, the declarations will read:

template <typename T, int = 0>
inline int test_sfinae(T tc);

template <typename T, /* Something that does not compile... */ = 0>
inline int test_sfinae(T ntc);

So the first overload will be chosen, and the inverse when T is not trivially copyable.

Holt
  • 36,600
  • 7
  • 92
  • 139
  • 1
    Yeap, that did the trick. Thanks ! Is there maybe a way to use the enable_if with the return value, to achieve the same result ? – Igor Mitrovic May 17 '18 at 13:34
  • Yes, just replace `int` with the whole `std::enable_if_t` expression (without the `= 0`), and it should do the same, but this is usually advised against. – Holt May 17 '18 at 13:50