2011-10-24 18 views
7

Vì vậy, tôi có một chức năng gọi là tìm kiếm, trong đó có hai phiên bản:Làm thế nào để sử dụng hai chức năng, một iterator trở về, các const_iterator trở khác

template <typename T> 
typename btree<T>::iterator btree<T>::find(const T& elem) 
{ 
    //Implementation 
} 

và thứ hai là phiên bản const_iterator:

template <typename T> 
typename btree<T>::const_iterator btree<T>::find(const T& elem) const 
{ 
    //Implementation 
} 

Trong tập tin thử nghiệm của tôi khi tôi làm

btree<char>::iterator it = myTree.find('M'); 

Tất cả mọi thứ hoạt động tốt, tuy nhiên khi tôi sử dụng const_iterat hoặc phiên bản:

btree<char>::const_iterator it = myTree.find('M'); 

Nó mang lại cho tôi những lỗi

error: conversion from 'btree_iterator' to non-scalar type 'const_btree_iterator' requested

Mà rõ ràng có nghĩa là tìm thấy là chỉ bao giờ sử dụng iterator (không const) phiên bản. Tôi biết rằng C++ được cho là sẽ tự động gọi phiên bản const_iterator - nếu tôi đã làm mọi thứ đúng. Câu hỏi đặt ra là, tôi có thể làm gì sai?

Các lớp iterator là:

class btree_iteratorclass const_btree_iterator mà chỉ là một bản sao của dán btree_iterator với những cái tên đã thay đổi

Dưới đây là toàn bộ mã nguồn:
btree_iterator.h (bao gồm const_btree_iterator) http://pastebin.com/zQnj9DxA
btree.h http://pastebin.com/9U5AXmtV
btree.tem http://pastebin.com/U9uV3uXj

+1

Cả hai phiên bản const và không const của trình biến đổi btree có thể nhìn thấy nơi bạn gọi myTree.find không? bạn có thể đăng toàn bộ tập tin không? – jopasserat

+0

Đã chỉnh sửa câu hỏi có liên kết đến mã nguồn – Arvin

Trả lời

9

Tất cả các container tiêu chuẩn thực hiện chuyển đổi không const để lặp const (như specified in the requirements for the Container concept):

The type of iterator used to iterate through a container's elements. The iterator's value type is expected to be the container's value type. A conversion from the iterator type to the const iterator type must exist.

Bạn cần constructor chuyển đổi như vậy:

class btree_iterator; 
class const_btree_iterator 
{ 
     // .... 
     public: 
       const_btree_iterator(const btree_iterator& rhs) { /* .... */ } 
//optionally: const_btree_iterator& operator=(const btree_iterator& rhs) { /* .... */ } 
}; 

tôi đã ném trong toán tử gán quá nhưng tôi giả sử nó là dư thừa

+0

Cảm ơn! Điều đó làm việc, và tôi thực sự nghĩ rằng C + + sẽ chỉ gọi phiên bản đúng của tìm bằng cách nào đó, nhưng tôi cho rằng đó không phải là trường hợp – Arvin

+1

Không. Nơi duy nhất mà tôi biết rằng 'quá tải độ phân giải' xuất hiện để _backtrack_ và tiếp tục cố gắng trong C + + là trong quy tắc SFINAE nổi tiếng (nó không thực sự bỏ qua quá tải, trên thực tế: nó là bỏ qua instantiations mẫu không) – sehe

5

Điều quan trọng ở đây là độ phân giải quá tải được thực hiện chỉ dựa trên các đối số cho hàm và không phải là kết quả. Trong trường hợp cụ thể của bạn, bạn có hai trạng thái quá tải khác nhau và sự khác biệt là hàm this ẩn trong một trong số chúng, quá tải sẽ được chọn bất cứ khi nào kiểu tĩnh của đối tượng hoặc tham chiếu mà phương thức được gọi là hằng số.

Nếu bạn muốn để buộc công văn đến tình trạng quá tải thường xuyên, bạn có thể lấy một tham chiếu const và sau đó gọi trên tham chiếu đó:

btree<char> const & r = myTree; 
btree<char>::const_iterator it = r.find('M'); 

Bạn nên tránh xây dựng này trong mã thực tế, ngay cả khi bạn sử dụng nó cho Mục đích thử nghiệm. Lý do là do quá tải const và không const nên có cùng ngữ nghĩa và do đó hành vi phải giống nhau. Cũng cần lưu ý rằng trong các thùng chứa tiêu chuẩn, có một chuyển đổi ẩn từ iterator thành const iterator để hỗ trợ sử dụng trực tiếp trên các thùng chứa không phải là const.Bạn nên làm như vậy, có nghĩa là, nếu bạn cung cấp một chuyển đổi ngầm iterator-const_iterator, sau đó bạn chỉ có thể viết:

btree<char>::const_iterator it = myTree.find('M'); 

... và nó sẽ làm việc (sẽ không kiểm tra phương pháp find, nhưng sẽ cho phép bạn xác minh hành vi const_iterator)

+0

Cảm ơn vì điều này, tôi cố định nó bằng cách sử dụng một chuyển đổi từ iterator để const_iterator như bạn đã đề cập – Arvin

+0

@Arvin Nó không rõ ràng với tôi cho dù * trong tập tin thử nghiệm của tôi * có nghĩa là bạn đang cố gắng để kiểm tra '' '' '' 'quá tải hoặc' const_iterator' hoặc chỉ container nói chung. –

+0

"trong tập tin thử nghiệm của tôi" có nghĩa là bên trong các chức năng chính trong một tập tin cpp riêng biệt mà kiểm tra thực hiện lớp btree của tôi. Tôi đã thực sự thử nghiệm các container nói chung và vấp ngã khi vấn đề này – Arvin

Các vấn đề liên quan