简体   繁体   中英

How does a templated class resolve an overloaded non-member function called on one of its types?

In the following example, I've created a mock Container class for an arbitrary type. Calling compare() on the Container calls compare() for the Value object stored inside. How is the compare() function overloaded for Value resolved in Container<Value> when it is declared afterwards and is not a member function of Value?

Code:

template<typename T>
class Container
{
public:
    Container(T value) : element(value) {}
    T element;
};

template<typename T>
int compare(Container<T> const& first, Container<T> const& second)
{
    return compare(first.element, second.element);
}

class Value
{
public:
    Value(int value) : value(value) {}
    int value;
};

int compare(Value const& first, Value const& second)
{
    if (first.value < second.value)
        return -1;
    else if (first.value > second.value)
        return 1;
    return 0;
}

int main()
{
    auto l1 = Container<Value>(1);
    auto l2 = Container<Value>(1);
    auto l3 = Container<Value>(2);

    cout << compare(l1, l2) << endl;
    cout << compare(l1, l3) << endl;
}

Output (as expected):

0
-1

模板只有在实例化时才会得到解析,因此您的compare Value方法只需要在main之前而不是在compare Container方法之前声明

It is because the argument dependent lookup (ADL).

The two arguments of the call compare(first.element, second.element) are of type Value , so the whole enclosing namespace of Value , ie, the global namespace, is searched, and the overload of compare for Value is found.

If you replace Value by a fundamental type, eg int , then there is no ADL and the code won't work:

template<typename T>
class Container
{
public:
    Container(T value) : element(value) {}
    T element;
};

template<typename T>
int compare(Container<T> const& first, Container<T> const& second)
{
    return compare(first.element, second.element); // error: no matching function for call to 'compare(const int&, const int&)'
}

int compare(int first, int second)
{
    if (first < second)
        return -1;
    else if (first > second)
        return 1;
    return 0;
}

int main()
{
    auto l1 = Container<int>(1);
    auto l2 = Container<int>(2);

    compare(l1, l2);
}

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