使用循环将元组数据写入文件

问题描述 投票:0回答:1

我想将元组写入/读取到 BIN 文件中。我知道如何写入/读取元组的每个元素,但元组有 13 个元素,我宁愿使用循环一次完成所有这些元素。但我一直没能做到。

这是我尝试过的代码:

#include <fstream>

template <typename T>
std::ostream& writeBin(std::ostream& f, T data) {
    return f.write(reinterpret_cast<char*>(&data), sizeof(data));
}
std::ostream& writeBin(std::ostream& f, const std::string& str) {
    std::string::size_type sz = str.size();
    if (f) { f.write(reinterpret_cast<char*>(&sz), sizeof(sz)); }
    if (f) { f.write(str.data(), str.size()); }
    return f;
}

template <typename T>
std::istream& readBin(std::istream& f, T& data) {
    if (f) { f.read(reinterpret_cast<char*>(&data), sizeof(data)); }
    return f;
}
std::istream& readBin(std::istream& f, std::string& str) {
    std::string::size_type sz = 0;
    if (f) { f.read(reinterpret_cast<char*>(&sz), sizeof(sz)); }
    if (f) { str.resize(sz); f.read(str.data(), sz); }
    return f;
}

class Data {
public:
    Data() {};
    ~Data() {};
    std::tuple<std::string, std::string, int, int, int, int, std::string, int, int, int, int, int, int>tup{
        " "," ",0,0,0,0," ",0,0,0,0,0,0
    };
    bool write(std::ofstream& f);
    bool read(std::ifstream& f);
};

bool Data::write(std::ofstream& f) {
    std::apply([](auto&&... tArg) {
        ((if (!writeBin(f, tArg)) { return false; }), ...);//doesnt work
        }, tup);
    return true;
}

bool Data::read(std::ifstream& f) {
    std::apply([](auto&&... tArg) {
        ((if (!readBin(f, tArg)) { return false; }), ...);//doesnt work
        }, tup);
    return true;
}
c++ iostream
1个回答
0
投票

您的意思是迭代元组的所有元素吗? 这就是

std::index_sequence
的用途:

C++20:

bool Data::write(std::ostream& f) {
    using Tuple = decltype(tup);
    return [&os=f]<std::size_t...I> (const auto& tup, std::index_sequence<I...>){
        return (writeBin(os, std::get<I>(tup)) && ...);
    }(tup, std::make_index_sequence<std::tuple_size_v<Tuple>>());
}

C++20之前的版本需要提供额外的辅助层,但原理大致相同:

template<typename Tuple, std::size_t...I>
static bool write_impl(
    std::ostream& f,
    const Tuple& t,
    std::index_sequence<I...>)
{
    return (writeBin(f, std::get<I>(t)) && ...);
}

bool Data::write(std::ostream& f) {
    return write_impl(f, tup, std::make_index_sequence<std::tuple_size_v<decltype(tup)>>());
}
© www.soinside.com 2019 - 2024. All rights reserved.