Шаблонная функция C ++ для массивов, векторов, встроенных типов, STL - PullRequest
5 голосов
/ 21 февраля 2012

Я хотел бы создать класс, который имеет функцию, которая сохраняет отправленные ему данные в текстовый файл.Данные, которые могут быть переданы ему, могут быть любыми: std::string, int, double, float, unsigned int и т. Д., А также могут быть: std::vector<T>, T[]std::vector<std::vector<T>>, T[][].

Теперь, очевидно, если это массив, мне нужно будет выполнить итерацию по нему, чтобы отправить данные в текстовый файл.

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

Это путь?

class CMyClass
{
    template<typename T>
    void SaveData(T data);
    void SaveData(std::vector<T> data);
    void SaveData(std::string data);
    void SaveData(T* data);                // Perhaps I'll also need to pass in the size.
    void SaveData(std::vector<std::vector<T>> data);
    void SaveData(T** data);
};

Я думаю, что код для std::string будеттакой же, как код для std::vector<T> при условии, что T является встроенным типом (например, int или float или что-то в этом роде).

И затем я пишу функции для каждого из SaveData(...) соответственно?

Ответы [ 2 ]

5 голосов
/ 21 февраля 2012

Во-первых, вы можете создать шаблон класса или функций. Поскольку вы также хотите создавать массивы, вы должны воспользоваться последним вариантом. Пример следует:

class CMyClass
{
public:
    template<typename T> void SaveData(const T &data);
    template<typename T, size_t N> void SaveData(const T (&data)[N]);
    template<typename T, size_t N, size_t M> void SaveData(const T (&data)[N][M]);
    template<typename T> void SaveData(const std::vector<T> &data);
    template<typename T> void SaveData(const std::vector<std::vector<T> > &data);
    void SaveData(const std::string &data);
};

Как только вы определили функции, в следующем примере показано, как вы можете их вызывать:

int i;
int i1[5];
int i2[5][7];
std::vector<int> v1;
std::vector<std::vector<int> > v2;
std::string s;

CMyClass saveClass;

saveClass.SaveData<int>(i);
saveClass.SaveData<int>(i1);
saveClass.SaveData<int>(i2);
saveClass.SaveData<int>(v1);
saveClass.SaveData<int>(v2);
saveClass.SaveData(s);

В зависимости от ваших требований вы можете сделать класс одиночным, а функции - статическими, исключив необходимость создания экземпляра CMyClass и просто вызывая функции следующим образом:

CMyClass::SaveData<int>(i);
CMyClass::SaveData<int>(i1);
CMyClass::SaveData<int>(i2);
CMyClass::SaveData<int>(v1);
CMyClass::SaveData<int>(v2);
CMyClass::SaveData(s);

Примечания:

  1. Аргументы также должны быть ссылками (т. Е. «& Data», а не «data»), так что передается только ссылка, а не выполняется копирование всего контейнера при каждом вызове функции.
  2. Я явно объявил функции как публичные, предполагая, что это полный класс, и к его функциям будет обращаться другой класс. По умолчанию члены класса являются частными.
  3. Убедитесь, что между каждым вложенным ">" есть пробел.

Удачи!

0 голосов
/ 21 февраля 2012

Я полагаю, что вы смешиваете две вещи в одном классе, чего следует избегать: насколько я понимаю, что ваш класс (его «ответственность») состоит в том, чтобы записывать данные в файл.Еще одна вещь, которую вы добавляете, - это знания об итерации коллекций данных.

Взгляните на <algorithm> методы STL:

http://www.cplusplus.com/reference/algorithm/

Там вы можете найти общиеспособы итерации данных, например, в методе find:

template<class InputIterator, class T>
  InputIterator find ( InputIterator first, InputIterator last, const T& value )
  {
    for ( ;first!=last; first++) if ( *first==value ) break;
    return first;
  }

Это делает вас независимым от того, используете ли вы vector, list, массивы или что-то еще.

Если вы также хотите сериализовать такие вещи, как vector<vector<T> > (обратите внимание на пробел между двумя >!), Вам нужно больше объяснить, что вы хотите делать с такими данными.Просто объедините элементы, как если бы все T были в одном vector?В этом случае вы можете попытаться создать новый итератор, который сделает именно это.

Библиотека итераторов буста может помочь с этим:

http://www.boost.org/doc/libs/1_48_0/libs/iterator/doc/index.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...