Home > front end >  Class member template function call not being deducted
Class member template function call not being deducted

Time:08-24

I am having trouble understanding why the following does not compile. I have the following code like so (some code ommited):

Header:

template <typename KeyType, typename ElementType>
class TUnorderedMap
{
public:
    ElementType* Find(const KeyType Key);
    const ElementType* Find(const KeyType Key) const;
};

struct Foo
{
};

Source file:

void Lookup()
{
    TUnorderedMap <Foo*, Foo> NodeToWidgetLookup;
    
    Foo TempFoo;
    const Foo* SelectionTarget = &TempFoo;

    // Issue here in this call
    NodeToWidgetLookup.Find(SelectionTarget);

    // Issue here in this call
    NodeToWidgetLookup.Find(SelectionTarget);
}

Error message: ErrorMessage What is the issue here? Why is neither of the Find functions accepted?

CodePudding user response:

What is the issue here? Why is neither of the Find functions accepted?

With the given instantiation

TUnorderedMap <Foo*, Foo> NodeToWidgetLookup;

The function Find expects a const pointer Foo *const:

const ElementType* Find(Foo* const Key) const;

While you are trying to pass a non-const pointer to const argument const Foo*:

const Foo* SelectionTarget

You can either change the template arguments like this:

TUnorderedMap <const Foo*, Foo> NodeToWidgetLookup;

Or make your argument point to a non-const instance:

Foo* SelectionTarget;

If you want to take all pointer overloads, you may want to declare an overload that is a function template itself:

template<typename Key>
const ElementType* Find(const Key* key) const {
    static_assert(std::is_same<Key*, KeyType>::value, "The types don't match");
    ...
}

The template ignores cv-qualifiers of the pointed to object of and the (outermost) pointer part of the argument, but it won't be applicable for non-pointer types.

Thanks to overload resolution rules you also can mix it with a non-template overload:

ElementType* Find(const KeyType Key);
const ElementType* Find(const KeyType Key) const;
template<typename Key> const ElementType* Find(const Key* key) const;

But be advised, that non-template functions in this scenario precede the function template in the overload resolution candidate list.

  • Related