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

zed*_*d91 3 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))
   {
    strlen((T*)initStr);
   }
   else if (typeid(T) == typeid(wchar_t))
   {
    wcslen((T*)initStr);
   }
  }
 }  
    ...
};
Run Code Online (Sandbox Code Playgroud)

当我编译代码时,我收到此错误消息:

...\main.cpp(32):错误C2664:'strlen':无法将参数1从'wchar_t*'转换为'const char*'

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

typedef size_t (*STRLEN)(void*);
STRLEN _strlen;
_strlen = reinterpret_cast<STRLEN> (typeid(*initStr) == typeid(char) ? strlen : wcslen);
Run Code Online (Sandbox Code Playgroud)

并且编译器再次发出错误,这次:

...\main.cpp(28):错误C2446:':':没有从'size_t(__ cdecl*)(const wchar_t*)'转换为'size_t(__ cdecl*)(const char*)'

我的问题是,我如何使用这些功能strlenwcslen模板?

vit*_*aut 7

你可以这样做,例如通过引入一个辅助函数,如下图所示:

#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");
}
Run Code Online (Sandbox Code Playgroud)

使用此辅助函数GetLength代替strlenwcslen不显式检查参数的类型.您也可以GetLength为其他类型编写重载,例如std::string.

你很少需要typeid在实践中使用,在这种情况下,这是完全不合适的.


小智 5

您不能使用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
  //...
Run Code Online (Sandbox Code Playgroud)

您还可以为char添加strlen的重载,然后您不需要using声明.