mardi 6 novembre 2018

Function template overloading with reference collapsing

In addition to this question, Function template deduction l-value reference and universal reference, I have another question. Note you do not have to read this post to understand this, but it might be helpful. This post does by the way not show the ideal solution to the problem I believe, but that's not the point.

template <typename Buf>
void copy (
    Buf&& input_buffer,
    Buf& output_buffer)
{} // 1)

template <typename Buf>
void copy (
    Buf& input_buffer, 
    Buf& output_buffer)
{} // 2)

...

int i = 4;
int j = 6;

copy<int&>(i, j); // copy taking two l-values; calls second instance.

I would expect if I were to call copy<int&>(i,j), the first instance of copy would be called. Type Buf is specified, so does not require to be deduced. Reference collision rules result in both input_buffer and output_buffer being l-value references. The first instance is the first valid function.

It is not a template specialization, so it does also surprise me that the compiler actually chooses either, in stead of giving an error.

The second instance of copy may appear more specified, but if Buf is int& the first instance also expects two l-value references.

So, the question is, why is the second instance preferred? I would expect that the compiler first actually creates the function, by substituting the template argument. Then, it turns out that Buf&& input_buffer in instance one is equal to Buf&.

Feel free to ask if I need to elaborate.

Aucun commentaire:

Enregistrer un commentaire