У меня такой код:
#include <iostream>
#include <type_traits>
template <typename T, typename std::enable_if
<std::is_convertible<int, T>::value, T>::type>
void func(T a)
{
std::cout << a << std::endl;
}
template <typename T, typename std::enable_if
<!std::is_convertible<int, T>::value, T>::type>
void func(T a)
{
a.print();
}
class Test
{
public:
void print()
{
std::cout << "Test" << std::endl;
}
};
int main()
{
func(3);
func("Test");
return 0;
}
С помощью этого кода я ожидал, что первый вызов func
распечатает 3
(поскольку int
действительно может быть преобразован в int
, должна быть вызвана первая специализация), а второй вызов func
для распечатки Test
(Test()
не преобразовывается в int
, поэтому вторую специализацию следует назвать). Однако вместо этого я получаю ошибку компилятора:
prog.cpp: В функции ‘int main ()’:
prog.cpp: 27: 8: error: нет соответствующей функции для вызова «func (int)»
prog.cpp: 5: 6: примечание: кандидат: шаблон [класс T, typename std :: enable_if [std :: is_convertible [int, T ›:: value, T› :: type ›void func (T)
prog.cpp: 5: 6: примечание: ошибка вывода / подстановки аргумента шаблона:
prog.cpp: 27: 8: примечание: не удалось определить параметр шаблона ‘[анонимный› ’
Если, однако, я заменю шаблонные функции на be (оставив все остальное точно так же):
template <typename T, typename std::enable_if
<std::is_convertible<int, T>::value, T>::type* =
nullptr>
void func(T a)
{
std::cout << a << std::endl;
}
template <typename T, typename std::enable_if
<!std::is_convertible<int, T>::value, T>::type* =
nullptr>
void func(T a)
{
a.print();
}
затем все компилируется и работает так, как я ожидал. Что делает этот дополнительный синтаксис и зачем он мне нужен?