Разве не было бы проще / чище заменить тип возврата метода enable_if?
Полагаю, это вопрос личного вкуса.
В любом случае, примите во внимание, что ваш пример
std::enable_if_t<!std::is_reference_v<T>>> f(T&& x){}
не работает, потому что SFINAE работает над шаблонамиконкретный метод.Итак, для вашего примера вы должны использовать шаблонный тип T_
(позвольте мне его назвать U
), а условие std::is_reference
должно оценивать U
, а не T
template <typename U = T>
std::enable_if_t<!std::is_reference_v<U>> f(T&& x){}
В любом случае, для обоих решений существует риск «угона»: вы можете обойти тест, объяснив тип U
myClassObject.template f<void>(aReference);
Чтобы избежать риска перехвата, вы должны также наложить T
иU
одного типа
template<typename U = T,
typename = std::enable_if_t<
!std::is_reference_v<U>
&& std::is_same_v<U, T>>>
void f(T&& x){}
template <typename U = T>
std::enable_if_t<
!std::is_reference_v<U>
&& std::is_same_v<U, T>> f(T&& x)
{ }