C ++テンプレートのメタプログラミング特化曖昧さ

だから私はテンプレートのメタプログラミングから始めて、文字列クラスを書いています。あまりにも多くのテンプレート関連の問題なしにToString、Concat、CharAt、Lengthを実装しました。私は以下のようにSubstringを実装しようとしていました:

struct Null;

// String class definition
template 
struct String {
  static const char chr = C;
  typedef S tail;
};

// Substring
// Gets the substring of length L starting at index I from string S.
template 
struct Substring;

template 
struct Substring<0, 0, S> {
  typedef Null substr;
};

// Will also cover I < 0 case
template 
struct Substring {
  typedef Null substr;
};

template 
struct Substring<0, L, String > {
  typedef String<0, L-1, S>::substr> substr;
};

template 
struct Substring > {
  typedef typename Substring::substr substr;
};

int main() {
 //This all works...
  typedef String<'H', String<'e', String<'l', String<'l',
            String<'o', Null> > > > > hello;
  typedef String<',', String<' ', Null> > comma;
  typedef String<'w', String<'o', String<'r', String<'l', String<'d',
            String<'!', Null> > > > > > world;
  typedef Concat::newstr>::newstr hello_world;
 //...up to here.
  typedef Substring<3, 5, hello_world>::substr mystr;
  return 0;
}

私がコンパイルすると、あいまいなエラーが出ます:

template.cpp:161: error: ambiguous class template instantiation for ‘struct
    Substring<0, 0, String<'o', String<'r', String<'l', String<'d', String<'!',
    Null> > > > > >’
template.cpp:149: error: candidates are: struct Substring<0, 0, S>
template.cpp:160: error:                 struct Substring<0, L, String >
template.cpp:165: error:                 struct Substring >
template.cpp:161: error: invalid use of incomplete type ‘struct Substring<0, 0, 
    String<'o', String<'r', String<'l', String<'d', String<'!', Null> > > > > >’
template.cpp:146: error: declaration of ‘struct Substring<0, 0, String<'o',
    String<'r', String<'l', String<'d', String<'!', Null> > > > > >’
template.cpp: In function ‘int main()’:
template.cpp:197: error: template argument 1 is invalid

私は少し混乱しています。私は、テンプレートの専門化の全体のポイントは、このようなものをすることだと思った。なぜこれは単に次のような拡張ではありません:

template 
struct Foo { ... }

template <>
struct Foo<0> { ... }

このあいまいさをどうやって修正するのですか?

ありがとう。

2
@sehe - それはパンで楽しくなるだろう!
追加された 著者 Nick,
んー。私はこのコードを見て疲れました。私の好みにはあまりにも実用的ではありません。私はあなたがMPLを学ぶためにそれを使うことに感謝します。このタイプのタスクでは、私はむしろ template String; を実行し、同時にvariadicテンプレートを学習したいのです:)(+1にもかかわらず)
追加された 著者 sehe,

1 答え

ここで 00 および任意のクラスSサブストリングを定義します。

template 
struct Substring<0, 0, S> {
  typedef Null substr;
};

Here you define a Substring with I, L and a String< C, S >:

template 
struct Substring > {
  typedef typename Substring::substr substr;
};

No one is a better candidate than the other, since one is a better match for I, L but a worse match for String< C, S >. If you were to declare the first case as:

template 
struct Substring<0, 0, String< C, S > > {
  typedef Null substr;
};

そうすれば、これは他のどのものよりも専門的になります。ただし、コードにはあいまいさがあります。

6
追加された
それは(唯一の)問題でした。ありがとう。
追加された 著者 Nick,