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_特征。