ENABL

发布于 2025-01-26 02:22:11 字数 777 浏览 2 评论 0原文

我知道C ++编译器优先选择一个模板专业化:

template<class T, class Enable = void>
class A {}; // primary template

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, void>> {
}; // specialization for floating point types

但是,我不明白为什么选择void以外的其他类型被用作参数to enable_if时,选择了。

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, int>> {
}; // specialization for floating point types

编译器肯定会“请参阅” a&lt; t,int&gt;。 因此,它当然不能是Sfinae,但是,主要模板比专业化更喜欢。

这个问题是从可以使用自定义类型检测机械而不是enable_if的上下文中引起的,例如common_type,例如sfinae友好型提取器。

I know that a C++ compiler picks a template specialization in preference to the primary template:

template<class T, class Enable = void>
class A {}; // primary template

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, void>> {
}; // specialization for floating point types

However, I don't understand why the selection fails when a type other than void is used as argument to enable_if:

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, int>> {
}; // specialization for floating point types

The compiler would surely "see" class A<T, int>.
So it certainly can't be SFINAE, nevertheless the primary template is preferred to the specialization.

This question arises from a context where a custom type detection machinery could be used instead of enable_if, e.g. an SFINAE friendly type extractor like common_type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏日浅笑〃 2025-02-02 02:22:11

如果您拥有

A<some_floating_point_type> some_name;

模板参数为some_floating_point_type和隐式void。当编译器实例化时,

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, int>> {
}; // specialization for floating point types

它将获得a&lt; some_floating_point_type,int&gt;,与a&lt; some_floating_point_point_type不匹配, 。因此,专业被忽略,您将获得主模板。您可以通过尝试创建一个a&lt; some_floating_point_type,int&gt;来验证这一点,并且您会选择选择专业化。

我发现将专业视为替代食谱很有帮助。首先,推导了模板参数,然后如果它们匹配任何专业,则我们切换到使用该替代配方。如果不是,则使用原始食谱。

When you have

A<some_floating_point_type> some_name;

The template parameters are some_floating_point_type and the implicit void. When the compiler instantiates

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, int>> {
}; // specialization for floating point types

it would get A<some_floating_point_type, int>, which does not match the A<some_floating_point_type, void> type that some_name has. Because of that, the specialization is ignored and you get the primary template. You can verify this by trying to create a A<some_floating_point_type, int> and you'll get that the specialization was picked.

I find it helpful to think of a specialization as an alternate recipe. First the template arguments are deduced, and then if they match any of the specializations, then we switch to using that alternate recipe. If not, then the original recipe is used.

半﹌身腐败 2025-02-02 02:22:11

在编译器知道将用于 primary 模板的类型之前,专业是无关紧要的。

当您编写a&lt; double&gt;时,编译器仅查看主模板,并看到您实际上是指a&lt; double,void&gt;

只有然后它正在寻找专业。现在,当您的专业化是a&lt; double,int&gt;时,它不合适,因为您要求a&lt; double,void&gt;

Specializations are irrelevant until the compiler knows which types it is going to use for the primary template.

When you write A<double>, then the compiler looks only at the primary template and sees that you actually mean A<double,void>.

And only then it is looking for specializations. Now, when your specialization is for A<double,int>, then it is not suitable because you asked for A<double,void>.

舂唻埖巳落 2025-02-02 02:22:11

简而言之,这

template<class T, class Enable = void>
class A {};

说明“ a是一个模板,它有两个参数,第二个参数具有void>”。多数民众赞成在主要模板。当您明确提供一个参数时,第二个参数是void

现在专业:

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, int>> {
};

这不会改变上述内容。 a仍然是一个带有2个参数的模板,当未指定第二个参数时,它是void。简而言之,这意味着“在t中替换std :: enable_if_t&lt&lt&lt&lt :: is_floating_point_point_voint_v&lt; t&gt;是失败,因为类型别名不存在”条件是false,Sfinae启动,并且专业化被忽略。当条件为true时:“每当A与参数t(某种类型)和int实例化时,然后使用此定义”。

当您实例化a&lt; int&gt;时,第二个模板参数为void。专业并没有改变这一点。那就是a&lt; int实际上是a&lt; int,void&gt;。它不符合专业化。

In simple terms, this

template<class T, class Enable = void>
class A {};

says "A is a template, it has two arguments, the second has a default that is void". Thats the primary template. When you explicitly provide only one parameter then the second argument is void.

Now the specialization:

template<class T>
class A<T, std::enable_if_t<std::is_floating_point_v<T>, int>> {
};

This doesn't change the above. A is still a template with 2 arguments and when the second one is not specified then it is void. In simple terms it either means "substituting T in std::enable_if_t<std::is_floating_point_v<T> is a failure, because the type alias does not exist" when the condition is false, SFINAE kicks in and the specialization is ignored. When the condition is true: "Whenever A is instantiated with arguments T (some type) and int then use this definition".

When you instantiate A<int> then the second template argument is void. The specialization does not change that. That is A<int> is actually A<int,void>. It does not match the specialiazation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文