1

我要做的就是实现相等的算法。但是,当我使用几个字符串进行测试时,会出现歧义错误。我认为编译器无法区分 A 和 B。这是为什么呢?

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)
4

2 回答 2

2

问题是参数(来自 的迭代器std::string)在命名空间中,并且在这个命名空间中,由于参数相关查找(ADL)std,还有另一种算法称为候选算法。equal您需要明确限定您的算法:

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

请注意,C++ 标准不要求迭代器是 in 的类型std,但允许它并且您的编译器/标准库决定使用此选项。

于 2013-11-04T18:29:14.227 回答
1

这是所谓的 Argument-Dependent Name Lookup 的结果。C++中有标准算法std::equal。编译器看到你的函数调用的参数属于命名空间 std。因此它还考虑了命名空间 std 中名称相等的任何函数。结果,它找到了两个函数:一个由您定义,另一个在命名空间 std 中声明。要转义错误,请使用函数的完全限定名称 ::equal。顺便说一句,您错误地使用了您的功能,并且这种用法具有未定义的行为。第二个范围必须至少与第一个范围具有相同的大小。在您的示例 wnen 中,您使用字符串 a 和 c,c 的大小小于 a 的大小。

于 2013-11-04T18:33:17.823 回答