Я хочу, чтобы все мои сохранения и загрузки данных проходили через одни и те же функции, чтобы уменьшить вероятность ошибок. Для этого я использовал много шаблонов (и много перегрузок функций). Это сработало, мой код теперь намного чище, но я не смог использовать const
для сохранения (потому что он выполняет те же функции, что и загрузчик, где данные хранятся неконстантно).
Я хотел бы использовать const
правильно, поэтому здесь делается попытка заставить работать простую версию, где данные (в данном случае std::vector
) неконстантны для std::ifstream
, а const
в противном случае:
#include <iostream>
#include <fstream>
#include <vector>
template <class Foo>
void Overload(const Foo & foo)
{
std::cout << "went to const" << std::endl;
}
template <class Foo>
void Overload(Foo & foo)
{
std::cout << "went to non-const" << std::endl;
}
template <class StreamType, typename... Arguments>
void ReadOrWrite (
/* for 1st argument */ StreamType & filestream,
/* type for 2nd argument */ typename std::conditional<
/* if */ std::is_same<StreamType, std::ifstream>::value,
/* then */ std::vector<Arguments...>,
/* else */ const std::vector <Arguments...>
>::type
/*2nd argument name */ & vector
)
{
Overload(vector);
}
int main ()
{
std::ofstream output_filestream;
std::ifstream intput_filestream;
std::vector<int> vector;
ReadOrWrite(output_filestream, vector);
ReadOrWrite(intput_filestream, vector);
return 0;
}
Я знаю, что он будет правильно скомпилирован / запущен, если я отредактирую вызовы функций для этого:
ReadOrWrite<std::ofstream, int>(output_filestream, vector);
ReadOrWrite<std::ifstream, int>(intput_filestream, vector);
Но я не хочу, чтобы пользователь функции нуждался вперечислите типы во время вызова функции.
Есть ли чистый способ сделать то, что я предлагаю?
РЕДАКТИРОВАТЬ
Кажется, естьвопрос о законности моего мотива.
Я не объяснил свой мотив полностью, потому что он не слишком прост (и не слишком сложен), и я уважаю время читателей.
ПримерЯ дал, был голый компонент того, что я не смог решить - и "оФункции verload были просто включены, чтобы посмотреть, сработало ли это.
Однако, похоже, мое отсутствие объяснения вызвало путаницу, поэтому я поясню:
Я сделал небольшую библиотеку для обработкиобщее сохранение и загрузка данных. Он успешно позволяет классам пользователей иметь простые методы сохранения / загрузки с помощью следующего интерфейса:
class SomeClass
{
public:
template <class StreamType>
void SaveOrLoad(StreamType & filestream)
{
saveload::SaveToOrLoadFromFile(filestream,
data_1_,
data_2_,
/* ..., */
data_n_,
);
}
void SaveToFile (const std::string & filename)
{
std::ofstream output_filestream(filename, std::ios::binary);
// file handling
SaveOrLoad(output_filestream);
}
void LoadFromFile (const std::string & filename)
{
std::ifstream input_filestream(ptf::problem_input_file, std::ios::binary);
// file handling
SaveOrLoad(input_filestream);
}
};
Эта библиотека обрабатывает все основные типы данных, контейнеры STL и любые другие контейнеры, которые используют правильный SaveOrLoad(StreamType &)
интерфейс, включая сохранение и изменение размера всех контейнеров. Библиотека заставила все сохранения и загрузки проходить одни и те же детерминированные функции и, следовательно, полностью устранила возможность ошибок, связанных с несовпадением сохранения / загрузки (если пользователь не использует простой интерфейс библиотеки).
проблема, с которой я столкнулся в своей библиотеке - и, следовательно, причина моего вопроса - является теоретической, потому что в настоящее время она мне не нужна: метод SaveToFile
должен быть в состоянии const
.