const char array (c style string) 模板特化

Posted

技术标签:

【中文标题】const char array (c style string) 模板特化【英文标题】:const char array (c style string) template specialization 【发布时间】:2011-11-01 00:18:22 【问题描述】:

我希望能够基于恒定的 c 样式字符串进行专业化。问题是当我调用我的模板化函数时,类型是 const char[N] 其中“N”是字符串 +1(空字符)的大小。我怎样才能专注于所有 c 风格的字符串?

以下代码显示了问题。您可以看到 const char [15] 的特化与“const char [15]”匹配,但对于“const char[5]”,它转到 Generic。

有没有办法做到这一点?

template <typename T>
struct Test 
  static const char* type()  return "Generic"; 
;

template <>
struct Test<const char*> 
  static const char* type()  return "const char*"; 
;

template <>
struct Test<const char[]> 
  static const char* type()  return "const char[]"; 
;

template <>
struct Test<const char[15]> 
  static const char* type()  return "const char[15]"; 
;

template <>
struct Test<char*> 
  static const char* type()  return "char*"; 
;

template <>
struct Test<char[]> 
  static const char* type()  return "char[]"; 
;

template <typename T>
void PrintType(const T& expected) 
  std::cerr << expected << " type " << Test<T>::type() << std::endl;

int main(int argc, char* argv[]) 
  const char* tmp = "const char*";
  PrintType(tmp);
  PrintType("const char[]");
  PrintType("const char[15]");
  PrintType("const char[5]");

在 Windows 7 - VS 2008 中运行时的输出

const char* type const char*
const char[] type Generic
const char[15] type const char[15]
const char[5] type Generic

【问题讨论】:

【参考方案1】:

任何chars 数组的特化是:

template< std::size_t N >
struct Test< const char[N] >  ... ;

但是,您不能再从 type() 返回 char*,除非您编写更多元函数来将非类型模板参数转换为其文本表示形式。

【讨论】:

type() 返回的 char* 仅用于调试目的。我也可以输出 1,2,3,4...。这是我的问题的一个虚构的例子。谢谢。【参考方案2】:

试试这个:

#include <cstdio>
#include <string>

template<class T>
void f2(const T& s) // Handle all kinds of string objects
 std::printf("string object: %s\n", s.c_str()); 

void f2(const char* s) // Handle const char*
 std::printf("const char*: %s\n", s); 

// ----------------------------------------------------------------------------

template<size_t N>
void f(const char(&s)[N]) // Handle const char array
 std::printf("const char[%zu]: %s\n", N, s); 

template<size_t N>
void f(char(&s)[N]) // Handle char array
 std::printf("char[%zu]: %s\n", N, s); 

template<class T>
inline void f(T&& s) // Handle other cases
 f2(std::forward<T>(s)); 

int main() 
  std::string stringObj     = "some kind of string object ...";
  char charArr[]            = "char array";
  const char constCharArr[] = "const char array";
  const char* constCharPtr  = "const char pointer";

  f(stringObj);
  f(charArr);
  f(constCharArr);
  f(constCharPtr);
  //f("const char array");

输出:

string object: some kind of string object ...
char[11]: char array
const char[17]: const char array
const char*: const char pointer

说明

f() 有两种重载:一种用于 char 数组,另一种用于“其他所有”。

f2() 处理“其他所有”情况。

【讨论】:

以上是关于const char array (c style string) 模板特化的主要内容,如果未能解决你的问题,请参考以下文章

初始化静态 const char* 数组

const char **,char *const *,char ** const

请问C语言如何把2个const char * const s1的字符串合并?

使用 `struct S const char *array[ARG_MAX]; 避免来自 `struct S as[] = NULL;` 的段错误;`? [复制]

从 const char* 参数中取出索引

C/C++ 将 char 数组初始化为 const char*