сообщество!
Помогите разобраться, почему следующий код не компилируется:
struct Format {};
template<typename F, typename ... Args>
void f(int, Args...) {}
template<typename F, typename T, typename ... Args>
void f(T, Args...) {}
int main () {
f<Format>(1, 1);
}
Что интересно, если поменять сигнатуру на
template<typename F, typename T, typename ... Args>
void f(F, T, Args...)
или убрать первый шаблонный параметр, компилируется нормально.
Можно добавить явную проверку типа первого аргумента функции и отбрасывать один из шаблонов по SFINAE:
#include <iostream>
#include <type_traits>
struct Format {};
template<typename F, typename T, typename ... Args>
::std::enable_if_t<::std::is_same_v<T, int>>
f(T, Args...) {std::cout << "1" << ::std::endl;}
template<typename F, typename T, typename ... Args>
::std::enable_if_t<!::std::is_same_v<T, int>>
f(T, Args...) {std::cout << "2" << ::std::endl;}
int main () {
f<Format>(1, 1);
f<Format>("sdf", 1);
}
online compiler
В случае, если проверяемый параметр более сложный, например шаблон, то можно реализовать дополнительную проверку:
#include <iostream>
#include <type_traits>
struct Format {};
template<typename T> struct Meta{};
template<typename T> struct
is_meta_wrapper: public ::std::false_type {};
template<typename T> struct
is_meta_wrapper<Meta<T>>: public ::std::true_type {};
template<typename T>
constexpr auto const is_meta_wrapper_v{is_meta_wrapper<T>::value};
template<typename F, typename T, typename ... Args>
::std::enable_if_t<is_meta_wrapper_v<T>>
f(T, Args...) {std::cout << "1" << ::std::endl;}
template<typename F, typename T, typename ... Args>
::std::enable_if_t<!is_meta_wrapper_v<T>>
f(T, Args...) {std::cout << "2" << ::std::endl;}
int main () {
f<Format>(Meta<int>{}, 1);
f<Format>(1, 1);
f<Format>("sdf", 1);
}
online compiler
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости