std::enable_if 基于 std::is_convertible 未正确推导模板
std::enable_if predicated on std::is_convertible not deducing template correctly
我有以下代码:
#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: In function ‘int main()’:
prog.cpp:27:8: error: no matching function for call to ‘func(int)’
prog.cpp:5:6: note: candidate: template [class T, typename std::enable_if[std::is_convertible[int, T>::value, T>::type > void func(T)
prog.cpp:5:6: note: template argument deduction/substitution failed:
prog.cpp:27:8: note: couldn't deduce template parameter ‘[anonymous>’
但是,如果我将模板函数更改为(同时保持其他一切完全相同):
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();
}
然后一切都按我预期的那样编译和工作。这个额外的语法有什么用,我为什么需要它?
template<typename T, typename std::enable_if<std::is_convertible<int, T>::value, T>::type>
如果我们去除噪音,会变成
template<typename T, typename Something<T>::type>
声明它的第二个参数是一个非类型参数,这里的 typename
指定嵌套的 type
是一个类型的名称。有关详细信息,请参阅 here。
在第一种情况下,第二个参数是非类型的,因此函数调用 func(3)
不适合期望 func<int, some_int>(3)
.
的模板
我有以下代码:
#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: In function ‘int main()’:
prog.cpp:27:8: error: no matching function for call to ‘func(int)’
prog.cpp:5:6: note: candidate: template [class T, typename std::enable_if[std::is_convertible[int, T>::value, T>::type > void func(T)
prog.cpp:5:6: note: template argument deduction/substitution failed:
prog.cpp:27:8: note: couldn't deduce template parameter ‘[anonymous>’
但是,如果我将模板函数更改为(同时保持其他一切完全相同):
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();
}
然后一切都按我预期的那样编译和工作。这个额外的语法有什么用,我为什么需要它?
template<typename T, typename std::enable_if<std::is_convertible<int, T>::value, T>::type>
如果我们去除噪音,会变成
template<typename T, typename Something<T>::type>
声明它的第二个参数是一个非类型参数,这里的 typename
指定嵌套的 type
是一个类型的名称。有关详细信息,请参阅 here。
在第一种情况下,第二个参数是非类型的,因此函数调用 func(3)
不适合期望 func<int, some_int>(3)
.