Tomasz Kaminski
Tomasz Kaminski

Reputation: 910

Ambiguous Call - Templated Function

I've been trying to brush up on my C++ knowledge and found this issue I cannot Google for easily.

I've written a function with the following signature:

template <typename Iterator>
Iterator lower_bound(
    Iterator left,
    Iterator right,
    typename Iterator::value_type const& target
) {
    //stuff happens here
}

and I'm trying to use it like so:

std::vector<int> odd{1, 2, 3, 4, 5, 6, 7};
int i = 4;
std::cout << std::distance(odd.begin(), lower_bound(odd.begin(), odd.end(), i)) << std::endl;

I'm getting the following compilation error: error: call to 'lower_bound' is ambiguous.

I'm guessing I'm lacking some understanding about how template types are resolved and so would be grateful for any resources that might explain this in a bit more detail.

Upvotes: 2

Views: 41

Answers (1)

StefanKssmr
StefanKssmr

Reputation: 1226

Here, std::lower_bound is causing the ambiguity. Due to Argument-dependent lookup your function as well as the std version are around.

If you use your own (non-std) iterator type, then you would not face any problem. See the example below (live demo):

#include <vector>
#include <iostream>

template <class T>
struct myIter {
    using value_type = T;
    myIter(T* const ptr) : ptr(ptr) {};
    T& operator*() {return *ptr;};
    T* ptr;
};

template <typename Iterator>
Iterator lower_bound(
    Iterator left,
    Iterator right,
    typename Iterator::value_type const& target) 
{
    return left;
}

int main()
{
std::vector<int> odd{1, 2, 3, 4, 5, 6, 7};
myIter<int> b(&(odd.front())), e(&(odd.back()));

int i = 4;
std::cout << *(lower_bound(b,e, i)) << std::endl; // <- works
// std::cout << *(lower_bound(odd.begin(),odd.end(), i)) << std::endl; // <- compiler error
}

Upvotes: 2

Related Questions