C++模板元编程专业化歧义

发布于 2024-12-12 07:44:23 字数 2722 浏览 0 评论 0原文

所以我刚刚开始使用模板元编程,并且我一直在编写一个字符串类。我实现了 ToString、Concat、CharAt 和 Length,没有出现太多与模板相关的问题。我试图按如下方式实现子字符串:

struct Null;

// String class definition
template <char C, class S>
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 <int I, int L, class S>
struct Substring;

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

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

template <int L, char C, class S>
struct Substring<0, L, String<C, S> > {
  typedef String<C, typename Substring<0, L-1, S>::substr> substr;
};

template <int I, int L, char C, class S>
struct Substring<I, L, String<C, S> > {
  typedef typename Substring<I-1, L, S>::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<hello, Concat<comma, world>::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<C, S> >
template.cpp:165: error:                 struct Substring<I, L, String<C, S> >
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 <int N>
struct Foo { ... }

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

我如何解决这种歧义?

谢谢。

So I'm just starting out with template metaprogramming and I have been writing a string class. I implemented ToString, Concat, CharAt, and Length without too many template-related problems. I was trying to implement Substring as follows:

struct Null;

// String class definition
template <char C, class S>
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 <int I, int L, class S>
struct Substring;

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

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

template <int L, char C, class S>
struct Substring<0, L, String<C, S> > {
  typedef String<C, typename Substring<0, L-1, S>::substr> substr;
};

template <int I, int L, char C, class S>
struct Substring<I, L, String<C, S> > {
  typedef typename Substring<I-1, L, S>::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<hello, Concat<comma, world>::newstr>::newstr hello_world;
  // ...up to here.
  typedef Substring<3, 5, hello_world>::substr mystr;
  return 0;
}

When I compile, I get an ambiguity error:

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<C, S> >
template.cpp:165: error:                 struct Substring<I, L, String<C, S> >
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

I'm a little confused. I thought the whole point of template specialization was to do stuff like this. Why isn't this just an extension of something like:

template <int N>
struct Foo { ... }

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

How do I fix this ambiguity?

Thanks.

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

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

发布评论

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

评论(1

徒留西风 2024-12-19 07:44:23

在这里,您定义一个带有 00 和任何 class SSubstring

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

这里您定义一个 SubstringILStringC, S >

template <int I, int L, char C, class S>
struct Substring<I, L, String<C, S> > {
  typedef typename Substring<I-1, L, S>::substr substr;
};

没有一个比另一个更好的候选者,因为一个与 I, L 匹配得更好,但与 String匹配得更差。 C、S>。如果您将第一种情况声明为:

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

那么这将比任何其他情况都更加特殊。但是,您的代码中可能存在其他歧义来源。

Here you define a Substring with 0, 0 and any class S:

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

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

template <int I, int L, char C, class S>
struct Substring<I, L, String<C, S> > {
  typedef typename Substring<I-1, L, S>::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 <char C, class S>
struct Substring<0, 0, String< C, S > > {
  typedef Null substr;
};

Then this would be more specialized than any other. However, there may be other sources of ambiguity at your code.

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