gpt4 book ai didi

c++ - SFINAE : Understanding void_t and detect_if

转载 作者:行者123 更新时间:2023-12-01 22:38:18 27 4
gpt4 key购买 nike

我正在学习模板元编程,最近,我看到了关于 CPPConference 的演讲。关于 void_t。不久之后,我发现了detection idiom .

但是,我仍然很难理解其中任何一个(尤其是检测习惯用法,因为它基于 void_t)。我读过this博客文章,以及this stackoverflow 帖子,这对我有一点帮助,但我仍然有一些问题。

如果我的理解是正确的,如果 void_t 内的表达式无效,则使用以下表达式将其删除:

template< class, class = std::void_t<> >
struct has_type_member : std::false_type { };

因为类在这里是一个默认模板参数,可以代表任意数量的参数,而与它们的类型无关?是否有必要说 class 等于 std::void_t<> ?写得还不够吗

template< class, class = void >
struct has_type_member : std::false_type { };

如果没有,为什么?

但是,如果表达式有效,则该表达式将被调用为 void:

template< class T >
struct has_type_member<T, std::void_t<typename T::type>> : std::true_type { };

为什么有效的表达式会被计算为 void,这对我们有什么帮助?另外,为什么表达式需要有效才能匹配 void_t?

最佳答案

好吧,我并不声称我自己已经完全理解了一切,但我会尽力回答我所知道的:

Because class is here a default template parameter that can represent any number of parameters independent of their type?

差不多了。该模板将匹配具有一两个模板参数的任何实例化,因此所有形式 has_type_member<T>has_type_member<T, U> 。这是由于

  • class匹配任何类型。但这并不特殊(您也可以写 class T 您只是不需要名称,因为您没有在声明中引用它)每个模板首先匹配所有类型,并且只能通过参数数量来区分。通常,我们要么通过一些 SFINAE 魔法(如 enable_if )进行约束,要么稍后通过部分模板规范获得更好的拟合。
  • class = void匹配每种类型,如上所述,并且根本不匹配任何类型,因为 void如果我们没有争论就填写。

我们只会将此模板实例化为 has_member_type<T> ,所以这永远是第一场比赛,但可能不是最好的比赛。但作为第一个匹配,它告诉我们:第二个模板参数必须是 void ,因为所有进一步的匹配必须是部分规范。否则我们就会产生歧义。想一想,如果第二个模板给我们 int 会发生什么?如果表达式有效。然后我们有两场比赛has_type_member<T, void>has_type_member<T, int> ,那么我们应该选择哪个呢?这就是为什么在成功案例中类型必须是 void然后这个重载也被选择,因为它更特殊。

Why would a valid expression be evaluated to void, and how does this help us? Also, why does the expression need to be valid to match void_t?

所以我已经回答了第一个问题的第二部分。关于第一点:想想 void_t 的定义:

template<class...>
using void_t = void;

所以,...匹配所有内容,无论类型和数量如何,不是吗?实际上它只匹配一个有效的类型,如果不是,它怎么会使用这个类型呢? (我知道它不使用该类型,但它必须能够使用。并且它不能使用无效类型)。因此它给了我们void传递的模板参数是否有效。所以在我们的用例中:

如果T具有成员类型 T::type , T::type是有效类型且 void_t<...>匹配它。所以我们得到void_t<T::type>此时,其值为 void ,适合主要但更特殊,所以我们接受它并得到 true_type .

如果我们没有类型成员怎么办?然后表达式 T::type无效,void_t<...>无法 mazch 它,因此部分规范无效,因此我们无法选择它,但这没问题,因为替换失败不是错误,所以我们继续使用我们已经找到的主模板。

Is it even necessary to say that class equals to std::void_t<> ? Wouldn't it be enough to write

template< class, class = void >
struct has_type_member : std::false_type { };

And if not, why?

是的,会的,演讲中也这样做了。 void_t<>字面意思是void 。我认为void_t只是为了与第二个规范更加一致。有void_t是必需的,因为我们需要这个模板。l

关于c++ - SFINAE : Understanding void_t and detect_if,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59276542/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com