为什么不允许在非类型参数中进行部分特化以使用嵌套模板参数

发布于 2024-11-06 23:09:55 字数 684 浏览 0 评论 0原文

我有这段代码

template<int N, bool C = true>
struct A;

template<int N>
struct A<N, !(N % 5)> {
  /* ... */
};

// should work
A<25> a;

,也就是说,对于可被 5 整除的数字 N,编译器应该使用部分特化。但是编译器不会接受这种部分专业化,因为标准要求它拒绝这样的代码,其中部分专业化的非类型参数引用参数并且不仅仅是一个参数(例如,A; 有效)。但这样做的原因是什么呢?

请注意,我可以简单地将代码更改为更冗长的示例,并且它是有效的。

template<bool> struct wrap;
template<int N, typename = wrap<true> >
struct A;

template<int N>
struct A<N, wrap<!(N % 5)> > {
  /* ... */
};

// should work
A<25> a;

这很好,因为它不再是非类型参数。但是规范禁止更直接的部分专业化的原因是什么?

I have this code

template<int N, bool C = true>
struct A;

template<int N>
struct A<N, !(N % 5)> {
  /* ... */
};

// should work
A<25> a;

That is, for numbers N that are divisible by 5, the compiler should use the partial specialization. But the compiler won't accept that partial specialization, because the Standard requires it to reject such code where a non-type argument of a partial specialization references a parameter and is not simply a parameter (like, A<N, N> would be valid). But what is the reason of doing so?

Note that I can simply change my code to a more wordy example and it is valid

template<bool> struct wrap;
template<int N, typename = wrap<true> >
struct A;

template<int N>
struct A<N, wrap<!(N % 5)> > {
  /* ... */
};

// should work
A<25> a;

This is fine because it's not a non-type parameter anymore. But what is the reason the spec forbids the more straightforward partial specialization?

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

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

发布评论

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

评论(2

入画浅相思 2024-11-13 23:09:55

我认为其中很多都是历史性的。最初根本不允许使用非类型模板参数。添加它们后,存在很多限制。当人们尝试不同的可能性并确认它们不会造成问题时,一些限制就被消除了。

其中一些最初的限制没有任何特殊原因仍然存在,除了没有人费心去改变它们这一事实之外。就像那里一样,其中许多都可以解决,因此删除它们通常不会造成任何特别的困难。主要归结为一个问题:是否有人足够关心这个特殊案例并就此写一篇论文。

I think a lot of it is historical. Non-type template parameters weren't originally allowed at all. When they were added, there were lots of limitations. As people tried different possibilities, and confirmed that they didn't cause problems, some of the limitations were removed.

Some of those original limitations remain for no particular reason beyond the fact that nobody bothered to work at changing them. Much like there, many of them can be worked around so removing them generally often wouldn't cause any particular difficulty. Mostly it comes down to a question of whether anybody cared enough about this particular case to write a paper about it.

不疑不惑不回忆 2024-11-13 23:09:55

部分特化要求非类型模板参数在编译时可解析。

此时,

template<int N>
struct A<N, !(N % 5)> {
  /* ... */
};

N 是一个可以取多个值的变量,编译器无法确定地计算 N % 5

您的示例实例化了 using

A<25> a;

,但您也可以

A<25> a1;
A<15> a2;

在这种情况下编译器如何选择 N 的值?它不能,所以它必须禁止该代码。

Partial specialisation requires that the non-type template argument be resolvable at compile time.

At this point

template<int N>
struct A<N, !(N % 5)> {
  /* ... */
};

N is a variable that can take more than one value and the compiler is unable to calculate N % 5 with certainty.

Your example instantiates a using

A<25> a;

but you could also have

A<25> a1;
A<15> a2;

How does the compiler choose a value for N in this scenario? It can't and so it has to disallow the code.

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