考虑以下代码:
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*)'
我的问题是,我如何使用这些功能strlen和wcslen模板?
你可以这样做,例如通过引入一个辅助函数,如下图所示:
#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代替strlen或wcslen不显式检查参数的类型.您也可以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声明.
| 归档时间: |
|
| 查看次数: |
742 次 |
| 最近记录: |