Шаблонный класс в C ++ - PullRequest
       21

Шаблонный класс в C ++

5 голосов
/ 18 августа 2010

Какова функция следующего класса шаблонов C ++? Я за построчными аннотациями:

template<class T> string toString(const T& t, bool *ok = NULL) {
         ostringstream stream;
         stream << t;
         if(ok != NULL) *ok = stream.fail() == false;
         return stream.str();
}

Это как метод Java toString()?

Ответы [ 7 ]

8 голосов
/ 18 августа 2010

По сути, он возьмет любой объект, у которого есть оператор <<, определенный для вывода в поток, и преобразует его в строку.При желании, если вы передадите адрес bool varaible, он установит его в зависимости от того, успешно ли выполнено преобразование. </p>

Преимущество этой функции в том, что после ее определения, как только вы определили operator <<для нового класса, который вы пишете, вы также сразу же получите для него метод toString (). </p>

 template<class T> 
 string toString(const T& t, bool *ok = NULL) 
 { 
         ostringstream stream;     // line A
         stream << t;              // line B
         if(ok != NULL) 
               *ok = (stream.fail() == false);  // line C
         return stream.str();      // Line D
} 
  • A - объявляет ostringstream - выходной поток, который записывает в строку
  • B - записать свой объект в этот поток, используя его оператор << </li>
  • C - установить * ok логическое значение для успеха / неудачи
  • D - преобразовать поток в стандартную строку и вернутьэто.
3 голосов
/ 18 августа 2010

Эта шаблонная функция принимает значение любого типа и указатель на bool.Он пытается использовать std::ostringstream для преобразования значения в std::string, используя преобразования форматирования, предоставляемые выходными потоками.Если параметр bool -pointer не равен NULL, функция записывает, завершилась ли операция потока значением этого указателя.

Таким образом можно написать:

std::string s = toString(123);

Нотакже можно написать:

bool succeeded;
std::string s = toString(something, &succeeded);
if (succeeded) { ... }

То есть функция позволяет проверить, было ли преобразование успешным.

1 голос
/ 18 августа 2010

На самом деле это просто шаблонная функция, а не класс.Он обеспечивает упрощенную семантику для преобразования в строку для любого типа, который может работать с ostringstream (все числовые типы будут работать и могут быть определены дополнительные пользовательские преобразования).Функция помещает значение в поток, а затем возвращает строковое представление потока.

1 голос
/ 18 августа 2010

Это не шаблонный класс.Это шаблонная функция / метод.И действительно, он пытается поместить аргумент «т» в поток.Операция может не завершиться успешно, если выходной поток (ostringstream) не поддерживает обработку ввода типа «T» (оператор «<<» не знает, как обрабатывать объекты типа T). </p>

1 голос
/ 18 августа 2010

Да и нет. Он работает с любым объектом, для которого оператор << был определен с ostream. Тот или любой объект, для которого ostringstream имеет перегруженный метод для обработки.

Либо рассматриваемый объект, который вы передаете в функцию, имеет следующее определение:

ostream& operator <<(ostream &os, MyObj &obj);

или это попадает в одну стандартную перегрузку. Вот список перегруженных функций, найденных в `ostream ', взятых из здесь :

ostream & operator << (bool & val); </p>

ostream & operator << (short & val); </p>

ostream & operator << (unsigned short & val); </p>

ostream & operator << (int & val); </p>

ostream & operator << (unsigned int & val); </p>

ostream & operator << (long & val); </p>

ostream & operator << (unsigned long & val); </p>

ostream & operator << (float & val); </p>

ostream & operator << (double & val); </p>

ostream & operator << (long double & val); </p>

ostream & operator << (const void * val); </p>

ostream & operator << (streambuf * sb); </p>

ostream & operator << (ostream & (* pf) (ostream &)); </p>

ostream & operator << (ios & (* pf) (ios &)); </p>

ostream & operator << (ios_base & (* pf) (ios_base &)); </p>

*** Следующие функции не являются членами, но являются глобальными функциями:

ostream & operator << (ostream & out, char c); </p>

ostream & operator << (ostream & out, подписанный символ c); </p>

ostream & operator << (ostream & out, unsigned char c); </p>

ostream & operator << (ostream & out, const char * s); </p>

ostream & operator << (ostream & out, const подписанные символы * s); </p>

ostream & operator << (ostream & out, const unsigned char * s); </p>

0 голосов
/ 18 августа 2010

@ Луна, то, что упомянул Уатиас, заключается в том, что тип параметра шаблона T в вашей функции template<class T> string toString(const T& t, bool *ok = NULL) { должен быть либо частью списка типов данных, либо тип T должен реализовывать оператор << в ostream.В противном случае функция потерпит неудачу. </p>

0 голосов
/ 18 августа 2010

Во-первых, это не класс, это просто функция.Вот аннотированная версия:

// This function accepts two parameters, one of which is a constant reference
// to any arbitrary type (the arbitrary type is referred to as T), and the 
// other is an optional pointer to boolean, which is NULL if left unspecified.

template<class T> string toString(const T& t, bool *ok = NULL) {

         // This instantiates an output string stream, which is a class provided
         // by the STL which works very much like std::cout except that the output
         // is stored in a string instead of sent to standard output.

         ostringstream stream;

         // This inserts the passed-in variable t into the stream. This requires
         // that a function operator<<(ostream&, const T&) exists for the 
         // particular type T that is the type of t. If it does not exist for some
         // T that this function is called on, there will be a compile error. This 
         // operator overload is provided by default for built-in types and some STL
         // types (such as std::string). The implementation of this function for any
         // given type T is responsible for doing whatever needs to be done to 
         // represent the value of t as a character stream. This is exactly what
         // happens when you write std::cout << t, except the result is sent to
         // a string inside the stringstream instead of to the console.

         stream << t;

         // If the user passed in a pointer-to-boolean, then check if the previous
         // line caused an error, and set the boolean to false if there was an error,
         // or true otherwise. An error might occur if the value in t can't be
         // represented as a string for whatever reason.

         if(ok != NULL) *ok = stream.fail() == false;

         // This returns the string that was created by the stream (e.g. what would
         // have appeared on the terminal if stream were instead std::cout)

         return stream.str();
}
...