Zeyu Zhang CN
Zeyu Zhang CN

Reputation: 51

how could I pass variable arguments and use them one by one in a loop

Here is a rudent prototype that I want to implement:

void save_keys(const string& savepth, const vector<string>& keys) {

    size_t n_samples = keys.size();
    stringstream ss;
    for (size_t i{0}; i < n_samples - 1; ++i) {
        ss << keys[i] << endl;
    }
    ss << keys[n_samples - 1];

    ss.clear(); ss.seekg(0, ios::beg);
    ofstream fout(savepth, ios::out);
    ss >> fout.rdbuf(); fout.close();
}

void save_keys_values(const string& savepth, const vector<string>& keys, const vecotr<int>& values) {

    size_t n_samples = keys.size();
    stringstream ss;
    for (size_t i{0}; i < n_samples - 1; ++i) {
        ss << keys[i] << "," << values[i] << endl;
    }
    ss << keys[n_samples - 1] << "," << values[i];

    ss.clear(); ss.seekg(0, ios::beg);
    ofstream fout(savepth, ios::out);
    ss >> fout.rdbuf(); fout.close();
}

We can see that the two function has very similar structure and logic, only difference is that: for save_keys(...), the stringstream works in this way: ss << keys[i], but for save_keys_values(...), the stringstream works in this way: ss << keys[i] << "," << values[i].

Is there a method that I can fuse the above two implementation together, so that I can write one function(such as save_func) and call it in different conditions leading to different behavior? Such as save_func(keys) and save_func(keys, values).

Edit 1: I can use -std=c++17 when I compile my code.

Upvotes: 2

Views: 78

Answers (1)

Jarod42
Jarod42

Reputation: 218138

Variadic template might help:

template <typename... Ts>
void save_keys_values(const std::string& savepth,
                      const std::vector<std::string>& keys,
                      const std::vector<Ts>&... values)
{
    if (((keys.size() != values.size()) || ...))
        return;
    size_t n_samples = keys.size();
    std::stringstream ss;
    const char* sep = "";
    for (size_t i{0}; i < n_samples; ++i) {
        ss << sep << keys[i];
        ((ss << ", " << values[i]), ...);
        sep = "\n";
    }

    ss.clear(); ss.seekg(0, ios::beg);
    ofstream fout(savepth, ios::out);
    ss >> fout.rdbuf(); fout.close();
}

Demo

Upvotes: 4

Related Questions