【发布时间】:2017-12-11 23:51:00
【问题描述】:
我有以下代码:
#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: 错误:没有匹配函数调用‘func(int)’
prog.cpp:5:6: 注意:候选:模板 [class T, typename std::enable_if[std::is_convertible[int, T>::value, T>::type > void func(T)
prog.cpp:5:6: 注意:模板参数推导/替换失败:
prog.cpp:27:8: 注意:无法推断模板参数‘[anonymous>’
但是,如果我将模板化函数改为 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();
}
然后一切都按照我的预期编译和工作。这个额外的语法有什么用?为什么我需要它?
【问题讨论】: