2013-12-21 2 views
2

В следующем коде я должен квалифицировать вызов equal() (в противном случае я получаю «неоднозначный вызов перегруженной функции»), но может вызывать неквалифицированный find(). Какая разница?Реализация equal() и find()

#include <iterator> 
#include <vector> 
#include <iostream> 

using std::vector; 
using std::cout; 
using std::endl; 

// Test whether the elements in two ranges are equal. 
// Compares the elements in the range [b,e) with those in the range 
// beginning at d, and returns true if all of the elements in both ranges match. 
template <class InIter1, class InIter2> 
bool equal(InIter1 b, InIter1 e, InIter2 d) 
{ 
    cout << "My equal()" << endl; 
    while (b != e) 
     if ((*b++) != (*d++)) 
      return false; 
    return true; 
} 

// Returns an iterator to the first element in the range [b,e) 
// that compares equal to t. If no such element is found, the function returns last. 
template <class InIter, class T> 
InIter find(InIter b, InIter e, const T& t) 
{ 
    cout << "My find()" << endl; 
    while (b != e) { 
     if (*b == t) 
      return b; 
     b++; 
    } 

    return e; 
} 

/* "Accelerated C++", ex. 8.2 */ 
int main() 
{ 
    static const int arr[] = {8, 7, 15, 21, 30}; 
    vector<int> vec(arr, arr + sizeof(arr)/sizeof(arr[0])); 

    cout << "equal() result: " << ::equal(vec.begin(), vec.end(), vec.rbegin()) << endl; 

    vector<int>::iterator iter = find(vec.begin(), vec.end(), 21); 
    if (iter == vec.end()) 
     cout << "did not find()" << endl; 
    else 
     cout << "find() result: " << *iter << endl; 

    return 0; 
} 

Я думаю, что это связано с аргументом зависимого поиска (см this question), но до сих пор не понимаю, почему эти два вызова различны.

+2

Учитывая, что вы используете 'std :: vector', а не' using namespace std; 'он выглядит как ADL yes. Если это так, то он просто не находит соответствующего 'std :: find'. Я не проверял, какие заголовки, которые вы включаете, гарантированно предоставит, но главным моментом является то, что в C++ они не гарантируются * not *, в свою очередь, включают другие стандартные заголовки lib. –

+0

@ Пользователи и hth. - Alf Кажется, вы правы (#include делает разницу). Если вы хотите добавить ответ, я соглашусь с ним. Благодарю. –

+1

Ну, Бенджамин написал, по сути, то же самое, что и ответ. :) –

ответ

2

Оказывается, что ваша стандартная реализация библиотеки приносит std::equal в из другого файла, который также не принесет в std::find(возможно, он используется для сравнения оператора вектора). Если вы включите <algorithm>, они оба будут включены, и вы получите двусмысленность для обоих случаев.