C++ 模板化代码如何在C+中找到类型为模板参数的字符串的长度+;?

C++ 模板化代码如何在C+中找到类型为模板参数的字符串的长度+;?,c++,templates,C++,Templates,考虑以下代码: template <typename T> class String { public: ... String(T* initStr) { size_t initStrLen; if (initStr != NULL) { printf_s("%s\n", typeid(T) == typeid(char) ? "char" : "wchar_t"); if (typeid(T) == typeid(char)) {

考虑以下代码:

template <typename T>
class String
{
public:
    ...
 String(T* initStr)
 {
  size_t initStrLen;
  if (initStr != NULL)
  {
   printf_s("%s\n", typeid(T) == typeid(char) ? "char" : "wchar_t");

   if (typeid(T) == typeid(char))
   {
    strlen((T*)initStr);
   }
   else if (typeid(T) == typeid(wchar_t))
   {
    wcslen((T*)initStr);
   }
  }
 }  
    ...
};
模板
类字符串
{
公众:
...
字符串(T*initStr)
{
初始尺寸;
if(initStr!=NULL)
{
printf_s(“%s\n”,typeid(T)=typeid(char)?“char”:“wchar_T”);
if(typeid(T)=typeid(char))
{
strlen((T*)initStr);
}
else if(typeid(T)=typeid(wchar\u T))
{
wcslen((T*)initStr);
}
}
}  
...
};
当我编译代码时,我收到了以下错误消息:

…\main.cpp(32):错误C2664:“strlen”:无法将参数1从“wchar\u t*”转换为“const char*”

然后我尝试使用函数指针:

typedef size_t (*STRLEN)(void*);
STRLEN _strlen;
_strlen = reinterpret_cast<STRLEN> (typeid(*initStr) == typeid(char) ? strlen : wcslen);
typedef大小(*STRLEN)(void*);
斯特伦(u STRLEN);
_strlen=reinterpret_cast(typeid(*initStr)==typeid(char)?strlen:wcslen);
编译器再次发出错误,这次是:

…\main.cpp(28):错误C2446:“:”:没有从“size\u t(\u cdecl*)(const wchar\u t*)”转换为“size\u t(\u cdecl*)(const char*)”


我的问题是,如何将函数
strlen
wcslen
与模板一起使用?

您不能使用if语句来控制模板的实例化代码:主体中的所有代码都必须适用于每个实例化

std::size_t strlen(wchar_t const *s) {
  return std::wcslen(s);
}

//...
String(T* initStr) {
  using std::strlen;  // bring into scope so unqualified call can find it
  std::size_t length = strlen(initStr);  // uses std::strlen or our strlen
  //...

您还可以为char添加strlen重载,这样就不需要使用声明。

您误解了模板。您不应在此处使用
typeid
来确定类型,而应使用模板专业化。

您可以这样做,例如通过引入助手功能,如下所示:

#include <iostream>
#include <string.h>

size_t GetLength(const char* s) { return strlen(s); }
size_t GetLength(const wchar_t* s) { return wcslen(s); }

template <typename T>
void PrintLength(T s)
{
    std::cout << GetLength(s) << std::endl;
}

int main()
{
    PrintLength("abc");
    PrintLength(L"abc");
}
#包括
#包括
size_t GetLength(const char*s){return strlen(s);}
size_t GetLength(const wchar_t*s){return wcslen(s);}
模板
空打印长度(ts)
{

std::cout如果OP对字符串在STL中的实现方式感兴趣,他们将使用一个名为char_traits的整个帮助器类。这个类除了静态成员函数外什么都没有,char_traits专门用于char和wchar_t,以使用C运行时库函数,如memmove

例如,您有一个返回值0的比较函数。如果类型为char,则可以使用memcmp。如果类型为wchar,则可以使用宽等效项

它的工作原理如下:

template< typename Element >
class char_traits
{
public:
   static int compare( const Element * left, const Element * right, size_t length )
   {
       for( const Element * end = left + length; left != end; ++left )
       {
          if( left < right )
             return -1;
          else if( left > right )
              return 1;
       }
       return 0;
   }
  // other functions
};

template <> class char_traits<char> // I think this is the syntax
{
public:
   int compare( const char * left, const char * right, size_t len )
   {
     return memcmp( left, right, len ); // more efficient than the general loop above
   }
  // other functions
};

// specialise also for wchar_t
模板
类特征
{
公众:
静态整数比较(常量元素*左、常量元素*右、大小\长度)
{
for(常量元素*end=left+length;left!=end;+left)
{
if(左<右)
返回-1;
else if(左>右)
返回1;
}
返回0;
}
//其他职能
};
模板类char\u traits//我想这就是语法
{
公众:
int比较(常量字符*左,常量字符*右,大小长度)
{
return memcmp(left、right、len);//比上面的一般循环更有效
}
//其他职能
};
//还专门从事wchar\u t

是的,但最好给出一个编码示例。vitaut使用了一种不同的方法,使用了一个重载函数。我的第一个想法也是专业化,但在这里,专业化实际上意味着编写2个版本的类,这完全可以在没有模板的情况下完成。std::basic_string使用专业化,而不是basic_string it自身,但具有char_特征。