C ++ Şablonu Metaprogramlama Uzmanlığı Belirsizlik

Bu yüzden sadece şablon meta programla başladım ve bir string sınıfı yazdım. Çok fazla şablonla ilgili sorun olmadan ToString, Concat, CharAt ve Length uygulamasını yaptım. Substring'i şu şekilde uygulamaya çalışıyorum:

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::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;
}

Derlerken, bir belirsizlik hatası alıyorum:

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

Biraz kafam karıştı. Şablon uzmanlığının tüm noktası bunun gibi şeyler yapmak olduğunu düşündüm. Neden böyle bir şeyin bir uzantısı değil?

template 
struct Foo { ... }

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

Bu belirsizliği nasıl giderebilirim?

Teşekkürler.

2
@sehe - Bir çörek üzerinde eğlenceli olacak!
katma yazar Nick, kaynak
mmmm. Bu koda bakmaktan yoruldum. Tatmam için çok pratik değil. MPL'yi öğrenmek için kullandığınızı takdir ediyorum. Bu tür bir görevle template String; yapmayı ve aynı anda variadic şablonları öğrenmeyi tercih ederim :) (+1 yine de)
katma yazar sehe, kaynak

1 cevap

Burada 0 , 0 ve class S ile Substring tanımlayabilirsiniz:

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;
};

O zaman bu, diğerlerinden daha uzman olacaktı. Ancak, kodunuzda başka belirsizlik kaynakları olabilir.

6
katma
Bu (sadece) problemiydi. Teşekkürler.
katma yazar Nick, kaynak