为什么SFINAE中使用void_t?

问题描述 投票:0回答:1

我打算让我的问题成为以下问题的后续:我们如何将 void_t 用于 SFINAE?。我明白了 void_t 是如何使用的。我不明白为什么有必要。

让我们以该问题为例并删除 void_t

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

// specialized as has_member< T , void > or discarded (SFINAE)
template< class T >
struct has_member< T , decltype( T::member ) > : std::true_type
{ };

如果我传入一个不带“member”的对象,它仍将默认为默认模板,而带有“member”的对象将实例化专业化。

为什么这种想法有缺陷?我认为这与主模板的第二个模板参数具有默认值(“class = void”)有关。但我不明白为什么这很重要。为什么专业化必须使用“void_t”来匹配默认参数?难道默认的全部意义不是可以被覆盖吗?我在哪里可以阅读有关 cppreference.com 主题的更多信息?

c++ templates void sfinae void-t
1个回答
0
投票

您的主模板除其他外指定第二个模板参数默认为

void
;因此,对于任何类型
A
has_member<A>
均表示
has_member<A, void>

现在,假设

A
有一个名为
member
类型为
int
的公共成员:

class A {
public:
    int member;
};

这意味着

decltype( T::member )
int
,因此您的模板特化提供了
has_member<A, int>
的特化。这是完全正确的!但这不是您想要的 — 您想要的是 has_member<A>
 的专业化,即 
has_member<A, void>

这有道理吗?

© www.soinside.com 2019 - 2024. All rights reserved.