Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;模板元编程专门化_C++_Templates_Metaprogramming_Template Specialization_Template Meta Programming - Fatal编程技术网

C++ C++;模板元编程专门化

C++ C++;模板元编程专门化,c++,templates,metaprogramming,template-specialization,template-meta-programming,C++,Templates,Metaprogramming,Template Specialization,Template Meta Programming,所以我刚开始使用模板元编程,我一直在编写一个字符串类。我实现了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 // Get

所以我刚开始使用模板元编程,我一直在编写一个字符串类。我实现了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;
}
struct空;
//字符串类定义
模板
结构字符串{
静态常量char chr=C;
尾巴;
};
//子串
//从字符串S中获取从索引I开始的长度为L的子字符串。
模板
结构子串;
模板
结构子串{
typedef-Null-substr;
};
//也将涵盖I<0的情况
模板
结构子串{
typedef-Null-substr;
};
模板
结构子串{
typedef字符串substr;
};
模板
结构子串{
typedef typename子字符串::substr substr;
};
int main(){
//这一切都有效。。。
typedef字符串hello;
typedef字符串逗号;
typedef字符串世界;
typedef Concat::newstr hello_world;
//…一直到这里。
typedef子字符串::substr mystr;
返回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.cpp:161:错误:“struct”的类模板实例化不明确
子串'
template.cpp:149:错误:候选项为:struct Substring
template.cpp:160:错误:struct Substring
template.cpp:165:错误:struct Substring
template.cpp:161:错误:无效使用不完整的类型“struct Substring”
template.cpp:146:错误:声明“struct Substring”
template.cpp:在函数“int main()”中:
template.cpp:197:错误:模板参数1无效
我有点困惑。我认为模板专门化的全部目的就是做这样的事情。为什么这不只是以下内容的扩展:

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

template <>
struct Foo<0> { ... }
模板
结构Foo{…}
模板
结构Foo{…}
我如何修正这种模糊性


谢谢。

在这里,您可以使用
0
0
和任何
类定义
子字符串

template <class S>
struct Substring<0, 0, S> {
  typedef Null substr;
};
没有一个比另一个更好的候选者,因为其中一个比
I,L
更匹配,但比
String
更匹配。如果您宣布第一个案例为:

template <char C, class S>
struct Substring<0, 0, String< C, S > > {
  typedef Null substr;
};
模板
结构子字符串>{
typedef-Null-substr;
};

那么这将比任何其他的都更加专业化。但是,您的代码可能存在其他歧义源。

mmmm。我看这个代码很累。对我来说太不实用了。我很感激你用它来学习MPL。对于这种类型的任务,我宁愿做
模板字符串并同时学习可变模板:)(+1)@sehe-在面包上会很有趣!那是唯一的问题。谢谢
template <char C, class S>
struct Substring<0, 0, String< C, S > > {
  typedef Null substr;
};