Shuzheng
Shuzheng

Reputation: 13840

Is it possible to fix an argument to a variadic template function?

I want to put a variable number of arguments into a buffer, and so I've overloaded the << operator to insert values into given buffer:

template<typename T, typename... Args>
void pack(T first, Args... args, std::vector<uint8_t> &buffer) {
    pack(args ..., buffer);
    buffer << first;
} 

void pack(std::vector<uint8_t> &buffer) { return; }

Since variadic template functions rely on recursion, my idea is to have a base case that returns the buffer and a recursive case that inserts the first argument into the buffer (after the recursive call).

However, if I run code like:

std::vector<uint8_t> buffer;
pack((uint8_t)0xFF, (uint32_t)0x0A, buffer);
hex_dump(buffer);

I get an error message saying:

In file included from main.cpp:2:0:
./misc.hpp:20:6: note: candidate: template<class T, class ... Args> void pack(T, Args ..., std::vector<unsigned char>&)
 void pack(T first, Args... args, std::vector<uint8_t> &buffer);
      ^~~~
./misc.hpp:20:6: note:   template argument deduction/substitution failed:
main.cpp:35:47: note:   candidate expects 2 arguments, 3 provided
     pack((uint8_t)0xFF, (uint32_t)0x0A, buffer);

How can I pass the buffer in the recursive case, so that I can append the value to partially filled buffer?

Upvotes: 0

Views: 407

Answers (1)

Jarod42
Jarod42

Reputation: 217235

Simpler would be to have your buffer at first argument:

void pack(std::vector<uint8_t> &) {}

template<typename T, typename... Args>
void pack(std::vector<uint8_t> &buffer, T first, Args... args) {
    buffer << first;
    pack(buffer, args ...);
}

And in C++17, with Fold expression, you may directly write:

template<typename T, typename... Args>
void pack(std::vector<uint8_t> &buffer, Args... args) {
    (buffer << ... << args);
}

Upvotes: 4

Related Questions