2011-02-02 12 views
7

Đoạn mã sau không thể biên dịch được. Lỗi này có vẻ là một số loại cuộc gọi không rõ ràng đối với thường trình hợp nhất. Sự hiểu biết của tôi là STL có một thủ tục hợp nhất được tìm thấy trong không gian tên std, nhưng theo như tôi có thể nói tên hợp nhất trong mã dưới đây phải là duy nhất.Lỗi trình biên dịch C++ không rõ ràng

Nếu tôi đổi tên hợp nhất thành xmerge, mọi thứ sẽ hoạt động. Vấn đề có thể là gì? xung đột tên đến từ đâu?

http://codepad.org/uAKciGy5

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

template<typename InputIterator1, 
     typename InputIterator2, 
     typename OutputIterator> 
void merge(const InputIterator1 begin1, const InputIterator1 end1, 
      const InputIterator2 begin2, const InputIterator2 end2, 
      OutputIterator out) 
{ 
    InputIterator1 itr1 = begin1; 
    InputIterator2 itr2 = begin2; 
    while ((itr1 != end1) && (itr2 != end2)) 
    { 
     if (*itr1 < *itr2) 
     *out = *itr1, ++itr1; 
     else 
     *out = *itr2, ++itr2; 
     ++out; 
    } 
    while (itr1 != end1) *out++ = *itr1++; 
    while (itr2 != end2) *out++ = *itr2++; 
} 

int main() 
{ 
    std::vector<int> l1; 
    std::vector<int> l2; 
    std::vector<int> merged_list; 

    merge(l1.begin(),l1.end(), 
     l2.begin(),l2.end(), 
     std::back_inserter(merged_list)); 

    return 0; 
} 
+0

Thông báo lỗi là gì? Trình biên dịch của tôi không phàn nàn, nó biên dịch mã tốt. – Oswald

+0

Biên dịch tốt ở đây. (gcc 4.4.3) –

+3

Tại sao tôi nên đặt tên khác? Tôi không sử dụng không gian tên std. –

Trả lời

16

Compiler là nhận nhầm lẫn giữa merge chức năng của bạn và std::merge định nghĩa trong algorithm. Sử dụng ::merge để xóa sự mơ hồ này. Cuộc gọi này không rõ ràng vì trình biên dịch đang sử dụng Argument Dependendent Lookup để tìm kiếm hàm khi tên hàm không đủ tiêu chuẩn được sử dụng.

+1

Đó là những gì tôi nghĩ là đang xảy ra nhưng không phải là thường lệ được trong không gian tên std? –

+7

@Reyzooti: Vấn đề là Argument Dependent Lookup ngụ ý rằng vì các kiểu được truyền tới hàm call được định nghĩa trong 'std', thì không gian tên' std' đi vào không gian tìm kiếm. Về cơ bản đây là những gì cho phép bạn viết 'std :: string (" Hi ") + std :: string (" there ")' bên ngoài 'namespace' std'. Toán tử '+' cho chuỗi được định nghĩa bên trong 'std', nhưng bạn chắc chắn muốn mã đó hoạt động mà không cần phải viết' std :: operator + (str1, str2) 'hoặc' str1.toán tử + (str2) ', tùy thuộc vào cách toán tử được xác định, điều mà tôi không quan tâm lắm. –

+5

@Reyzooti: Có, phiên bản thư viện chuẩn của 'thư viện' nằm trong không gian tên' std' - nhưng ADL vẫn khiến nó được coi là ứng cử viên vì các đối số cho hàm là từ không gian tên 'std' (để biết chi tiết) về cách ADL hoạt động, xem bài viết trên Wikipedia). –