SFINAE: удалить функцию с тем же прототипом
Интересно, в чем разница между этим кодом, который работает:
#include <type_traits>
#include <iostream>
template<typename T> using is_ref = std::enable_if_t<std::is_reference_v<T>, bool>;
template<typename T> using is_not_ref = std::enable_if_t<!std::is_reference_v<T>, bool>;
template<typename T, is_ref<T> = true>
void foo(T&&) {
std::cout << "ref" << std::endl;
}
template<typename T, is_not_ref<T> = true>
void foo(T&&) {
std::cout << "not ref" << std::endl;
}
int main() {
int a = 0;
foo(a);
foo(5);
}
и этот, который не работает:
#include <type_traits>
#include <iostream>
template<typename T> using is_ref = std::enable_if_t<std::is_reference_v<T>, bool>;
template<typename T> using is_not_ref = std::enable_if_t<!std::is_reference_v<T>, bool>;
template<typename T, typename = is_ref<T>>
void foo(T&&) {
std::cout << "ref" << std::endl;
}
template<typename T, typename = is_not_ref<T>>
void foo(T&&) {
std::cout << "not ref" << std::endl;
}
int main() {
int a = 0;
foo(a);
foo(5);
}
В чем истинная разница между typename = is_ref<T>
а также is_ref<T> = true
?
1 ответ
Если вы удалите аргументы шаблона по умолчанию, станет ясно, в чем разница. Объявления функций не могут отличаться только по умолчанию. Это плохо сформировано:
void foo(int i = 4);
void foo(int i = 5);
И также это плохо сформировано:
template <typename T=int> void foo();
template <typename T=double> void foo();
Имея это в виду, ваш первый случай:
template<typename T, is_ref<T>>
void foo(T&&);
template<typename T, is_not_ref<T>>
void foo(T&&);
Два объявления здесь уникальны, потому что второй параметр шаблона отличается между двумя объявлениями. Первый имеет нетипизированный параметр шаблона, тип которого std::enable_if_t<std::is_reference_v<T>, bool>
а второй имеет параметр шаблона нетипичного типа, тип которого std::enable_if_t<!std::is_reference_v<T>, bool>
, Это разные типы.
Принимая во внимание, что ваш второй случай:
template<typename T, typename>
void foo(T&&);
template<typename T, typename>
void foo(T&&)
Это явно та же подпись - но мы только что ее дублировали. Это плохо сформировано.