I'm building a minimal binary parser/serializer for one of my projects and I got this error that seems inconsistent at first. I have two top functions I want to expose T parse<T>(bytes)
and bytevec serialize<T>(T const&)
and from these two templated functions I delegate the serialization to overloaded functions based on the specific type provided. The problem is that the parsing side works fine, but the serialization side doesn't compile because it cannot see the overloaded function if it is defined after the top serialize
function.
using bytevec = std::vector<uint8_t>;
using bytes = std::span<const uint8_t>;
template <typename T>
bytevec serialize(T const& data) {
bytevec b{};
serialize(data, b); // error: no matching function for call to 'serialize(const int&, bytevec&)
return b;
}
void serialize(int data, bytevec& b) {
b.push_back(0xff);
b.push_back(0xaa);
}
template <typename T>
struct tag {};
template <typename T>
T parse(bytes b) {
return parse(b, tag<T>{}); // fine
}
int parse(bytes b, tag<int>) { return b[1]; }
void test() {
static std::array<uint8_t, 2> data{0xff, 0xaa};
auto res1 = parse<int>(std::span(data));
auto res2 = serialize(res1);
}
Why is it ok for the top parse
function to call an overloaded function defined later (int parse(bytes, tag<int>)
and for the serialize
function the overloaded function needs to be defined before in order to compile?
Thank you