为什么函数参数的类型推导优先于模板中的类型



让我们看看enable_if使用的简单示例

template <bool, typename T = void>
struct enable_if
{
};
template <typename T>
struct enable_if<true, T>
{
typedef T type;
};
  1. 这里预期y将是int,因为T是我们的";启用";类型
template <typename T, typename Y = typename std::enable_if<std::is_integral<T>::value, T>::type>
void do_stuff(T t)
{
(void)t;
Y y;
std::cout << typeid(y).name() << std::endl;
}
do_stuff(15); // int
  1. 但这里的情况对我来说有些不明确,y将被推导为实际参数的类型
template <typename T, typename Y = typename std::enable_if<std::is_integral<T>::value, T>::type>
void do_stuff(T t, Y y)
{
(void)t;
std::cout << "do_stuff integraln";
std::cout << typeid(y).name() << std::endl;
}
do_stuff(15, 14.3);  // double

所以我的问题是:

什么规则会迫使编译器从传递的实际参数中优先推导y,而忽略enable_if中启用的type

只有在未显式指定模板参数且无法推导模板参数时,才使用默认模板参数。在这种情况下,Y可以从14.3推导为double,那么就不会使用默认参数。类似地,在第一个示例中,您也可以通过指定模板参数来绕过对std::enable_if的检查。

do_stuff<int, double>(15); // double

顺便说一句,您可以在类型声明中使用std::enable_if添加非类型模板参数,使检查始终生效。

template <typename T, typename Y, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
void do_stuff(T t, Y y)

相关内容

  • 没有找到相关文章

最新更新