简体   繁体   中英

Implementing equal algorithm

All I'm trying to do is implement the equal algorithm. However, when I test with a few strings, I get an ambiguity error. I think the compiler cannot differentiate between the A and the B. Why is this?

template <class A, class B> bool equal(A beg, A end, B out)
{
    while(beg != end) {
        if(*beg == *out) {
            ++beg;
            ++out;
        }
        else return false;
    }
    return true;
}

MAIN

std::string a("This is a string");
std::string b("This is a string");
std::string c("String c");
std::cout << "a and b are " << equal(a.begin(), a.end(), b.begin()) << std::endl;
std::cout << "a and c are " << equal(a.begin(), a.end(), c.begin()) << std::endl;

ERROR MESSAGE

procedures_main.cpp:17:35: error: call to 'equal' is ambiguous
    std::cout << "a and b is " << equal(a.begin(), a.end(), b.begin()) << std::endl;
                                  ^~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:1105:1: note: 
      candidate function [with _InputIterator1 = std::__1::__wrap_iter<char *>, _InputIterator2 =
      std::__1::__wrap_iter<char *>]
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
^
./procedures.hpp:73:34: note: candidate function [with A = std::__1::__wrap_iter<char *>, B = std::__1::__wrap_iter<char
      *>]
template <class A, class B> bool equal(A beg, A end, B out)

The problem is that the arguments (the iterators from std::string ) are in the namespace std and in this namespace, there is another algorithm called equal which is a candidate due to argument dependent lookup (ADL). You need to explicitly qualify your algorithm:

std::cout << "a and b are " << ::equal(a.begin(), a.end(), b.begin()) << std::endl;
//                             ^^ here

Note that the C++ standard does not require the iterators to be a type in std , but is allows it and you compiler/standard library decided to use this option.

This is the result of the so-called Argument-Dependent Name Lookup. There is standard algorithm std::equal in C++. The compiler sees that arguments of your function call belong to namespace std. So it also takes into consideration any function with name equal in namespace std. As the result it finds two functions: the one that is defined by you and the other that is declared in namespace std. To escape the error use fully qualified name of your function that is ::equal. By the way you use your function incorrectly and such a usage has undefined behaviour. The second range must have at least the same size as the first range. In your example wnen you use strings a and c the size of c is less than size of a.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM