#include <algorithm>
#include <vector>
template <class BidirectionalIterator, class UnaryPredicate>
BidirectionalIterator partition(BidirectionalIterator first,
BidirectionalIterator last, UnaryPredicate pred)
{
while (first != last) {
while (pred(*first)) {
++first;
if (first == last) return first;
}
do {
--last;
if (first == last) return first;
} while (!pred(*last));
std::swap(*first, *last);
++first;
}
return first;
}
int main() {
std::vector<int> v = { 1, 55, 17, 65, 40, 18, 77, 37, 77, 37 };
partition(v.begin(), v.end(), [](const int &i) {
return i < 40;
});
return 0;
}
The code won't compile. Both clang++(3.5.2/cygwin) and Visual Studio(2013) complain about ambiguous call. Since no using
directive is used, I don't understand what's wrong.
To compile successfully, using ::
prefix helps.
prog.cpp:25:11: error: call of overloaded ‘test (char)’ is ambiguous When there is no exact type match, the compiler looks for the closest match. The closest match for “test (‘a’);” will be “void test (int a)”, since it is not present, void test (double d) and void (float f)will cause ambiguity.
In Function overloading, sometimes a situation can occur when the compiler is unable to choose between two correctly overloaded functions. This situation is said to be ambiguous. Ambiguous statements are error-generating statements and the programs containing ambiguity will not compile.
The abs function included by <cstdlib> is overloaded for int and long and long long. Since you give a double as the argument, the compiler does not have an exact fit, so it tries to convert the double to a type that abs accepts, but it does not know if it should try to convert it to int, long, or long long, hence it's ambiguous.
The verbatim error is: Call to 'abs' is ambiguous. The compiler offers three versions of abs, each taking a different datatype as a parameter. What's happened is that you've included <cstdlib> (indirectly, since it's included by iostream) along with using namespace std;.
Your partition
has a name collision with std::partition
The reason it is doing so, even without the std::
prefix is because it is using argument dependent lookup (ADL) on the arguments, which are std::vector<int>::iterator
, which carry the std::
namespace. Therefore, the compiler is able to "see" the std::partition
function as well as your partition
function.
From cppreference (emphasis mine)
... for every argument in a function call expression and for every template argument of a template function, its type is examined to determine the associated set of namespaces and classes that it will add to the lookup
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With