Всем привет, мне нужно построить код внутри шаблона который тоже будет шаблоном Вот мой код
class A
{
public:
template <typename T1, typename T2>
A(T1 y, T2 d, T1 t, T2 f, T1 w, T2 l)
{
ofstream out;
out.open(d, ofstream::app);
out.write((char*)& y, sizeof(y));
out.close();
// очередная копия кода
out.open(f, ofstream::app);
out.write((char*)& t, sizeof(t));
out.close();
// снова копия о боже мой
out.open(l, ofstream::app);
out.write((char*)& w, sizeof(w));
out.close();
}
};
Как видите он находится внутри класса A и шаблона template используя шаблон я вызываю эту функцию таким способом
int main()
{
A(777, "1.bin", 666, "2.bin", 555, "3.bin");
}
Проблема в том что мне нужно создать много файлов но я не хочу каждый раз копировать код ofstream.
А так же я не могу использовать код не внутри класса A и шаблона template, все переменные и их работа выполняется только там. Если я перемещаю этот код в отдельный класс он не может передавать прочитанные данные другой переменной или другому классу, получается все работает только внутри класса A и шаблона template. Пытался создать наследования классов но один фиг классы хранят данные только внутри себя и не могут передавать данные между шаблона template. Скорее всего я где то ошибся или чего то не знаю. Надеюсь на подержу и много разных примеров.
Обновления для AlexGlebe
using namespace std;
public:
template <typename T1, typename T2, typename T3, typename T4>
A(T1 y, T2 d, T1 t, T2 f, T3 w, T4 l, T5 h, T2 r, T3 z, T4 n) {
ifstream in;
open_in<T3, T5>(in, y, d);
// тут начинается другой код который дальше работает с переменными
// например простой цикл который должен получить данные y и продолжить
// свое выполнения подсчетов, но к сожалению он получает старые данные
// которые были добавлены в main
// A("1.bin", "2.bin", "3.bin", 666, 555, 111, 955635332, 333, 777, 10);
ofstream out;
open_out<T1,T2>(out, y, d);
}
private :
// первый сохраняет
template <typename T1, typename T2>
void open_out(ofstream & out,T1 a, T2 b) {
out.open(b, ofstream::app);
out.write((char*)& a, sizeof(a));
out.close();
}
// второй читаем данные
template <typename T1, typename T2>
void open_in(ifstream & in,T1 a, T2 b) {
in.open(b, ios::binary);
in.read((char*)& a, sizeof(a)))
in.close();
}
};
// main
A("1.bin", "2.bin", "3.bin", 666, 555, 111, 955635332, 333, 777, 10);
Код который читай данные не передает их на переменную y и d в итоге мы получаем старые данные, когда снова попадаем в класс A
И на самом деле я бы хотел вытащить это отдельно от класcа A иначе мне потом сложно будет работать с этим годом.
Может я не понял, но вот мой ответ:
# include <fstream>
class A
{
public:
template <typename T1, typename T2>
A(T1 y, T2 d, T1 t, T2 f, T1 w, T2 l)
{
std::ofstream out;
openwriteclose<T1,T2>(out, y, d);
openwriteclose<T1,T2>(out, t, f);
openwriteclose<T1,T2>(out, w, l);
}
private :
template <typename T1, typename T2>
void openwriteclose(std::ofstream & out,T1 y, T2 d){
out.open(d, std::ofstream::app);
out.write((char*)& y, sizeof(y));
out.close(); }
};
int main()
{
A(777, "1.bin", 666, "2.bin", 555, "3.bin");
}
Второй вариант со списком любого размера :
# include <fstream>
# include <list>
class A
{
public:
template <typename T1, typename T2>
A(std::list<std::pair<T1,T2>> & list)
{
std::ofstream out;
for(std::pair<T1,T2> & j : list){
out.open(j.second, std::ofstream::app);
out.write((char*)& j.first, sizeof(j.first));
out.close(); }
}
};
int main()
{
std::list<std::pair<int,char const * > > args={{777, "1.bin"},{ 666, "2.bin"},{ 555, "3.bin"}};
A a(args);
}
Все варианты, что пришли в голову, как мог написал.
В шаблонах я не эксперт, поэтому variadic templates написал как умел.
Тут на выбор три варианта:
Использовать оператор <<.
Использовать метод write, который возвращает ссылку на объект, и позволяет сделать цепочку вызовов
Variadic templates, почти то что вы хотели.
#include <fstream>
#include <iostream>
#include <string>
class Example{
public:
template<typename T>
const Example& write(const T& y, const std::string& d) const{
std::ofstream out;
out.open(d, std::ofstream::app);
out.write(reinterpret_cast<const char*>(&y), sizeof(y));
out.close();
return *this;
}
struct FilePath{
std::string filepath;
};
template<typename T>
Example& operator<<(const T& t){
std::ofstream out;
out.open(m_filepath, std::ofstream::app);
out.write(reinterpret_cast<const char*>(&t), sizeof(t));
out.close();
return *this;
}
Example& operator<<(const FilePath& fp){
m_filepath = fp.filepath;
return *this;
}
template<typename T>
struct DataForWriteToFile{
T data;
std::string filepath;
};
template<typename... Args>
void writeToFile(Args... args){
writeToFile(std::forward<Args>(args)...);
}
template<typename T, typename... Args>
void writeToFile(const DataForWriteToFile<T>& t, Args... args){
write(t.data, t.filepath);
writeToFile(std::forward<Args>(args)...);
}
template<typename T>
void writeToFile(const DataForWriteToFile<T>& t){
write(t.data, t.filepath);
}
private:
std::string m_filepath = "tmp.bin";
};
int main(){
Example e;
using Data = Example::DataForWriteToFile<int>;
e.write(777, "1.bin").write(666, "2.bin").write(555, "3.bin");
e << Example::FilePath{"11.bin"} << 777 << Example::FilePath{"22.bin"} << 666 << Example::FilePath{"33.bin"} << 555;
e.writeToFile(Data{777, "111.bin"}, Data{666, "222.bin"}, Data{555, "333.bin"});
return 0;
}
Простой вариант с функтором, принимающим два параметра:
#include <fstream>
#include <memory>
#include <type_traits>
#include <utility>
class BatchWrite
{
public: template<typename Data, typename Path> BatchWrite &&
operator ()(Data const & data, Path const & path) const
{
static_assert(::std::is_standard_layout_v<Data>);
::std::ofstream out{};
out.exceptions(::std::ofstream::badbit bitor ::std::ofstream::failbit bitor ::std::ofstream::eofbit);
out.open(path, ::std::ofstream::app bitor ::std::ofstream::binary);
out.write(reinterpret_cast<char const *>(::std::addressof(data)), sizeof(data));
return ::std::move(*this);
}
};
int main()
{
BatchWrite{}(777, "1.bin")(666, "2.bin")(555, "3.bin");
return 0;
}
Продвижение своими сайтами как стратегия роста и независимости