How can template code find the length of a string whose type is a template parameter in C ++?

Consider this code:

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);
   }
  }
 }  
    ...
};

When I compiled the code, I received this error message:

... \ main.cpp (32): error C2664: 'strlen': cannot convert parameter 1 from 'wchar_t *' to 'const char *'

Then I tried using a function pointer:

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

and again the compiler threw an error, this time:

... \ main.cpp (28): error C2446: ':': no ​​conversion from 'size_t (__cdecl *) (const wchar_t *)' to 'size_t (__cdecl *) (const char *)

My question is: how can I use the functions strlenand wcslentemplates?

+3
source share
4 answers

, . , :

#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");
}

GetLength strlen wcslen . GetLength , . std::string.

typeid , .

+7

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
  //...

strlen char, using.

+5

. typeid , .

+3

In the case where the OP is interested in how strings are implemented in the STL, they use the entire invocation of the char_traits helper class. This is a class in which there is nothing but static member functions, and char_traits is specialized for char and wchar_t to use C runtime library functions such as memmove.

For example, you have a comparison function that returns the value <0, 0, or> 0. If the type is char, it can use memcmp. Where is the type wchar_t, it can use a wide equivalent.

It works something like this:

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
+1
source

Source: https://habr.com/ru/post/1772336/


All Articles