Элегантность решения с шаблонами (CharTraits)
От: rg45 СССР  
Дата: 22.03.08 11:18
Оценка: 3 (1)
#Имя: FAQ.cpp.CharTraits
Здравствуйте, tomek, Вы писали:

T>Здравствуйте.

T>Мне необходимо написать класс строки , используя шаблоны. Предполагается, что будет два типа строк: юникодные и анси.
T>И вот мне требуется так сделать, чтобы использовать юникодные ф-ии в случае, если я инстанциируют CTestString<wchar_t> some. Ну и соответственно , анси варианты в случае CTestString<char> some.

Тут можно использовать достаточно распространенный прием: все особенности, которые отличают один тип символов от другого, оформить в виде отдельного шаблонного класса CharTraits, и сделать специализации этого шаблона, для тех типов символов, которые мы собираемся использовать в шаблонном классе строки:
#include <iostream>
#include <string>

//Объявление общего шаблона traits'ы для всех типов символов
//(Только объявление, определения делаются только для конкретных типов символов)
template<typename> class CharTraits;

//Определение нашего типа строки использует шаблон CharTraits,
//таким образом, оно абстрагировано от конкрктных типов символов
template<typename T>
class CTestString 
{
  typedef CharTraits<T> Traits;
public:

  CTestString(const T* str) 
    : m(new T[Traits::Length(str) + 1])
  {
    Traits::Copy(m, str);
  }
  ~CTestString() 
  {
    delete[] m;
  }
  
  const T* Value() {return m;}

private:
  T* m;  
};  

//Далее можем определять traits'ы для разных типов символов
template<> 
class CharTraits<char>
{
public:
  static size_t Length(const char* str) {return strlen(str);}
  static void Copy(char* dst, const char* src) {strcpy(dst, src);}
};

template<> 
class CharTraits<wchar_t>
{
public:
  static size_t Length(const wchar_t* str) {return wcslen(str);}
  static void Copy(wchar_t* dst, const wchar_t* src) {wcscpy(dst, src);}
};

//Примеры использования:
int main() 
{
  typedef CTestString<char> String;
  typedef CTestString<wchar_t> WString;
  
  String str = "This is the ANSI string";
  WString wstr = L"This is the Unicode string";
  
  std::cout << str.Value() << std::endl;
  std::wcout << wstr.Value() << std::endl;
}
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.