为什么主模板必须有default = void

void_t spezialization why does primary template has to have default = void?

本文关键字:default void 为什么      更新时间:2023-10-16

我有一个关于void_t元函数的问题,在这个视频中显示https://www.youtube.com/watch?v=a0FliKwcwXE和41:25问的问题。

我将尝试用下面的代码片段显示我的问题:
template<typename _Tp, typename _Up, typename = void>
class __is_assignable_helper_af2: public std::false_type
{
};

template<typename _Tp, typename _Up>
class __is_assignable_helper_af2<_Tp, _Up,
     void_t<decltype(std::declval<_Tp&>() = std::declval<_Up&>())>> 
  : public std::true_type
{
};

为什么第一个模板需要默认类型void ?Int不能工作

我所理解的是,这两个函数将具有相同的签名(带有void),但将使用更专门的签名(第二个)。但是为什么它不能用int呢?第二个带void的仍然是首选的,不是吗?

=int是否不匹配SFINAE ?

谢谢!

void是必需的,这样void_t<decltype(...)>表达式的结果将与主模板的默认参数匹配。

考虑类可赋值和不可赋值的情况:

可转让的

:

void_t<decltype(std::declval<_Tp&>() = std::declval<_Up&>())>
//reduces to
void_t<type given from assignment>
//reduces to
void

不可赋值:

void_t<decltype(std::declval<_Tp&>() = std::declval<_Up&>())>
//substitution failure, remove from candidate set

现在在可赋值的情况下,部分专门化只会在模板参数匹配的情况下被选择,也就是说,它们需要是这样的形式:

__is_assignable_helper_af2<_Tp, _Up, void>

我们希望客户端代码只传递两个参数,而不是显式地为SFINAE指定void参数,因此我们在默认参数中指定它:

template<typename _Tp, typename _Up, typename = void>
//                                   ^^^^^^^^^^^^^^^

我们可以很容易地选择void以外的类型,但是使用它会显式地表明我们不关心类型,我们只是使用它来利用SFINAE。例如,我们可以定义int_t,并将int作为默认实参。只要它们匹配,我们就可以在需要时使用部分专门化。