简体   繁体   中英

Why this template specification doesn't work for reference?

Consider the following code, where I have a template specification for a reference to structure. It seems that the function doesn't recognize that specification and continue use the original template definition.

If I get rid of the & operators in the template specification, I get a worked program.

#include <iostream>
template <typename T>
T larger(T a, T b);

struct point
{
    double x;
    double y;
};

template <> point& larger(point & p1, point & p2);

int main()
{   
    using namespace std;
    point p1 = { 1.1, 2.2 };
    point p2 = { 3.3, 4.4 };
    point &q1 = p1; // this is already a reference to 'point'
    point &q2 = p2;
    point q3 = larger(q1, q2);  // neither this
    point q4 = larger(p1, p2);  // nor this works

    cin.get();
    cin.get();
}

template <typename T>
T larger(T a, T b)
{
    return a > b ? a : b;
}


template <> point& larger(point& p1, point& p2) 
{
    return p1.x*p1.y > p2.x * p2.y ? p1 : p2;
}

Template argument deduction is a complex thing, between qualifiers, references, etc. You can easily get lost.

What you can do here is to define your template function as taking universal references:

struct point
{
    double x;
    double y;
};

template <typename T>
T larger(T&& a, T&& b)
{
    return a > b ? a : b;
}

template<> point& larger(point& p1, point& p2) 
{
    return p1.x*p1.y > p2.x * p2.y ? p1 : p2;
}

int main()
{   
    point p = { 1.1, 2.2 };
    point& rp = p;
    point max = larger(rp, rp); // deduced: point& larger<point&>(point&, point&)
}

demo: http://coliru.stacked-crooked.com/a/78441512a5fa85aa


Or you can avoid Template argument deduction altogether:

template <typename T>
T larger(T a, T b)
{
    return a > b ? a : b;
}
// ...
point max = larger<point&>(rp, rp);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM