40

私はこのコードを持っています

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

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

// should work
A<25> a;

つまり、でN割り切れる数値5の場合、コンパイラは部分的な特殊化を使用する必要があります。ただし、コンパイラはその部分的な特殊化を受け入れません。これは、標準では、部分的な特殊化の非型引数がパラメータを参照し、単なるパラメータではない(たとえば、A<N, N>有効である)コードを拒否することを要求しているためです。しかし、そうする理由は何ですか?

コードをもっとわかりやすい例に変更するだけで、有効であることに注意してください。

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;

型以外のパラメータではなくなったため、これで問題ありません。しかし、仕様がより単純な部分的特殊化を禁止している理由は何ですか?

4

2 に答える 2

15

その多くは歴史的なものだと思います。型以外のテンプレートパラメータは、元々許可されていませんでした。それらが追加されたとき、多くの制限がありました。人々がさまざまな可能性を試し、問題を引き起こさないことを確認したため、いくつかの制限が削除されました。

それらの元々の制限のいくつかは、誰もそれらを変更することにわざわざ取り組んでいないという事実を除いて、特別な理由なしに残っています。そこと同じように、それらの多くは回避できるため、通常、それらを削除しても特に問題は発生しません。ほとんどの場合、この特定のケースについて誰かがそれについての論文を書くのに十分気にかけているかどうかという問題に帰着します。

于 2011-05-12T20:52:49.813 に答える
-5

部分的な特殊化では、型以外のテンプレート引数がコンパイル時に解決可能である必要があります。

この時点で

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

Nは複数の値をとることができる変数であり、コンパイラーはN % 5確実に計算できません。

あなたの例は、使用をインスタンス化します

A<25> a;

しかし、あなたも持つことができます

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

このシナリオでは、コンパイラはどのようにNの値を選択しますか?それはできないので、コードを禁止する必要があります。

于 2011-05-12T16:12:02.163 に答える