busebd12
busebd12

Reputation: 997

How to re-write templated function to handle type deduction

So, I have this search function for the map container:

    template <typename Key, typename T>
    void searchInMapByKey(std::map<Key,T> Map, T keyValue)
    {
        if(Map.empty())
        {
            std::cout << "Map is empty, nothing to search for..." << "\n";
        }
        else
        {
            for(const auto & element : Map)
            {
                if(element.first==keyValue)
                {
                    std::cout << keyValue << "matches a key value " << " in the map" << "\n";
                }
            }
        }
    }

and I seem to be running into deducing type issues, specifically this error:

candidate template ignored: deduced conflicting types for parameter 'T' ('std::__1::basic_string<char>' vs. 'int')

when I try to test it with the following code:

        map<int,string> myMap;
        myMap.emplace(1,string("a"));
        myMap.emplace(2,string("b"));
        myMap.emplace(3,string("c"));
        searchInMapByKey(myMap,1);

Because the compiler doesn't know which type to associate with the "T", integer or string.

Now, I asked a similar question about the same type of error and was able to solve the issue by using C++ style strings. However, I don't want to keep handling conflicting type deduction errors on a case by case basis, and was wondering how I could write this function (using templates) to help the compiler better deduce which type should be associated with the "T" from the outset?

Upvotes: 1

Views: 113

Answers (3)

Michael Anderson
Michael Anderson

Reputation: 73480

The problem is a mismatch between the type of the Map and the key types. But I would fix it not by correcting the order of the parameters std::map argument, but by changing the definition to be more generic.

template <typename MapType, typename KeyType>
void searchInMapByKey(const MapType & Map, KeyType key) {
    if(Map.empty()) {
        std::cout << "Map is empty, nothing to search for..." << "\n";
        return;
    }      

    for(const auto & element : Map) {
        if(element.first==keyValue) {
            std::cout << keyValue << "matches a key value " << " in the map" << "\n";
        }
    }
}

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 172894

You're using the mapped_type of map, T for your key value, you should use key_type, so change the declaration of function to:

template <typename Key, typename T>
void searchInMapByKey(std::map<Key,T> Map, Key keyValue)

Upvotes: 1

Marshall Clow
Marshall Clow

Reputation: 16670

You're telling the compiler that the function searchInMapByKey has two parameters: a map<Key, T>, and a T.

For the call, you're passing map<int, string> and an int

From the first parameter, it deduces that Key=int and T=string.

From the second parameter, it deduces that T=int.

So it tells you that it has a conflict.

Upvotes: 1

Related Questions