if predicated on std::is
I have the following code:
#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;
}
With this code, I expected the first call to func
to print out 3
(as int
is indeed convertible to int
, the first specialization should be called) and the second call to func
to print out Test
( Test()
is not convertible to int
, so the second specialization should be called). However, I instead get a compiler error:
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>'
If, however, I change the templated functions to instead be (while leaving everything else exactly the same):
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();
}
then everything compiles and works as I expected. What is this extra syntax doing and why do I need it?
template<typename T, typename std::enable_if<std::is_convertible<int, T>::value, T>::type>
if we were to remove the noise, would become
template<typename T, typename Something<T>::type>
which is declaring as its second parameter a non-type parameter, the typename
here is specifying the nested type
is a name of a type. See here for more information.
In the first case, the second parameter is non-type, so the function call func(3)
doesn't fit the template which is expecting func<int, some_int>(3)
.
上一篇: std :: function vs模板
下一篇: 如果以std :: is为基础的话