C++ function template: can't match the best function

Viewed 56

I try to write different types of C++ variable to a byte array, this is my code:


    typedef unsigned char byte;

    template<typename T>
    using remove_rcv = typename std::remove_cv_t<std::remove_reference_t<T>>;
    
    template<typename T>
    size_t write(byte* p, T&& x) {
        static_assert(std::is_trivial_v<T>, "write() do not support this type");
        const byte* px = reinterpret_cast<const byte*>(&x);
        for (int i = 0; i < sizeof(remove_rcv<T>); i++) {
            p[i] = px[i];
        }
        return sizeof(remove_rcv<T>);
    }
    template<typename T>
    size_t write(byte* p, const std::vector<T>& x) {
        size_t len = 0;
        for (int i = 0; i < x.size(); i++) {
            len += write(p + len, x[i]);
        }
    }

As you can see, I use the first write function to write a built-in type or a simple struct and the second one to write a vector<T>

But in this code:

byte buf[1024];
std::vector<int> v = { 12,34,56 };
write(buf, v);

The write(buf, v); will call the first function, why?

Isn't the second function matches this invoke best?

I find the only way to make it work is this: write<int>(buf, v); but I don't want to do so because write will be invoked in another template function.

Then what can I do to solve it?

Edit:

I tried to modify the second function to a plain one:

size_t write(byte* p, const std::vector<int>& x) {
    size_t len = 0;
    for (int i = 0; i < x.size(); i++) {
        len += write(p + len, x[i]);
    }
}

It can't be matched either. How strange!

2 Answers

Change T&& to const T& since x[i] is not int&&, it's const int&.

Try it on godbolt.org: Demo.

Change the signature of the first function to const T& then the second function is a better match.

    template<typename T>
    size_t write(byte* p, const T& x) 

    template<typename T>
    size_t write(byte* p, const std::vector<T>& x)
Related