idealistikz
idealistikz

Reputation: 1267

Call of overloaded template function is ambiguous

I have the following code.

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm>

template <typename Type> inline Type max(Type t1, Type t2) { 
    return t1 > t2 ? t1 : t2; 
}

template <typename Type> inline Type max(const std::vector<Type> &vec) { 
    return *std::max_element(vec.begin(),vec.end());
} 

template <typename Type> inline Type max(const Type *parray, int size) {
return *std::max_element(parray,parray+size);
} 

int main(int argc, char *argv[]) {
    std::string sarray[] = {"we","were","her","pride","of","ten"};
    std::vector<std::string> svec(sarray,sarray+6);

    int iarray[] = {12,70,2,169,1,5,29};
    std::vector<int> ivec(iarray,iarray+7);

    float farray[] = {2.5,24.8,18.7,4.1,23.9};
    std::vector<float> fvec(farray,farray+5);

    int imax = max(max(ivec),max(iarray,7));
    float fmax = max(max(fvec),max(farray,5));
    std::string smax = max(max(svec),max(sarray,6));

    std::cout << "imax should be 169  -- found: " << imax << '\n'
              << "fmax should be 24.8 -- found: " << fmax << '\n'
              << "smax should be were -- found: " << smax << '\n';
    return 0; 
} 

I am attempting to implement two simple template functions to output the max element of a vector and an array. However, I am receiving the following error when the type is a string.

error: call of overloaded 'max(std::string, std::string)' is ambiguous

Why is this occuring, and what is the best way to remedy it?

Upvotes: 0

Views: 4546

Answers (3)

user2121617
user2121617

Reputation: 46

Your code

std::string smax = max(max(svec),max(sarray,6));

translates to:

std::string smax = max(string ,string ); 

After max(svec) and max(sarray,6) are evaluated using your templates. Now here the problem arises: The standard library already comes with a templated max() function. The compiler will be unable to tell whether you want your version of max() or std::max(). Now you will ask why it worked for integers and floats. Answer is in this line you are specifically mentioning std::string. Hence the compiler is getting confused. There can be work arounds. But since you need the best solution, I would say rename your max function say MAximum.

Upvotes: 3

Misch
Misch

Reputation: 10840

Why is this occuring?
The compiler error already tells you why. It does not know which version of max to use.

note: candidates are:
main.cpp:6:38: note: Type max(Type, Type) [with Type = std::basic_string]
...
/usr/include/c++/4.7/bits/stl_algobase.h:210:5: note: const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = std::basic_string]

Solution:
either explicitely call your max function or just call std::max (which already exists, so why would you want to reimplement it?).

Additionally, there is one ; too much after << "fmax should be 24.8 -- found: " << fmax << '\n'

Upvotes: 0

Kyle Lutz
Kyle Lutz

Reputation: 8036

The problem is that the compiler is finding multiple matching definitions of max via ADL and it doesn't know which to choose.

Try changing the call to max to use its qualified-id:

std::string smax = ::max(max(svec),max(sarray,6));

Upvotes: 4

Related Questions