2012-05-29 37 views
6

Làm thế nào để xóa loại từ các trình vòng lặp đầu ra là std::insert_iteratorstd::back_insert_iterator? Có thể sử dụng boost any_iterator để làm như vậy không?Trình lặp đầu ra loại C++ bị xóa loại

#include <boost/range.hpp> 
#include <boost/range/detail/any_iterator.hpp> 
#include <vector> 

typedef boost::range_detail::any_iterator< 
    int, boost::incrementable_traversal_tag, int &, std::ptrdiff_t > It; 

int main() 
{ 
    std::vector<int> v; 
    It outIt(v.begin()); // compiles 
    It inserter(std::back_inserter(v)); // does not compile 
    return 0; 
} 
+0

Bạn có ý nghĩa gì với "loại xóa"? –

+0

@EitanT: Bạn nên tìm kiếm "C++ type erasure", nhưng đối với một định nghĩa ngắn "quá trình chuyển nhiều loại khác nhau với một giao diện chung thành một loại với cùng giao diện đó". Boost :: Any sẽ là ví dụ kinh điển. –

+0

@ JesseGood Aaa Tôi biết đó là gì, tôi không bao giờ biết nó được gọi là "loại tẩy xoá". Doh! –

Trả lời

6

any_iterator không được thiết kế để sử dụng với lặp đầu ra, đó là back_insert_iterator là gì (hoặc, cho rằng vấn đề, lặp đầu vào).

back_insert_iterator được xác định kế thừa từ iterator<output_iterator_tag, void, void, void, void> ví dụ của nó value_type, reference_type, distance_typepointer_type đều void, nhưng any_iterator hy vọng để có thể gián tiếp thông qua iterator sự ủng hộ của mình cho một giá trị không hiệu lực. Có lẽ nó sẽ tốt hơn có tên là any_value_iterator; nhưng sau đó là mẫu lớp học detail.

+0

Cảm ơn bạn. Có bất kỳ lựa chọn thay thế trong Boost? –

+0

Không phải là tôi biết; vấn đề là 'boost :: iterator_facade' hy vọng có thể định nghĩa' operator [] 'và' operator-> 'trong lớp. Không quá khó để định nghĩa bản thân bằng cách sử dụng hàm 'boost ::' để bọc' toán tử = '(là phần duy nhất của trình lặp đầu ra thực sự quan trọng). – ecatmur

3

Vì vậy, tôi đã triển khai ứng dụng của riêng mình bằng Boost.

#include <boost/function_output_iterator.hpp> 
#include <boost/function.hpp> 

template < class T > 
class AnyInserter : public boost::function_output_iterator< boost::function< void (const T & value) > > 
{ 
private: 
    typedef typename boost::function_output_iterator< boost::function< void (const T & value) > > BaseType; 
    template < class OutIt > struct Insert 
    { 
     Insert(OutIt it) : m_it(it) {} 
     void operator() (const T & value) { m_it++ = value; } 
     OutIt m_it; 
    }; 
public: 
    template < class OutIt > 
     explicit AnyInserter(const OutIt & it) : BaseType(Insert<OutIt>(it)) {} 
}; 

template < class OutIt > 
    inline AnyInserter< typename OutIt::container_type::value_type > 
    makeAnyInserter(const OutIt & it) 
    { 
     return AnyInserter< typename OutIt::container_type::value_type >(it); 
    } 
+2

Điều đó có vẻ ổn. Một điểm là thay vì 'typename OutIt :: container_type :: value_type' bạn có thể muốn sử dụng' typename std :: iterator_traits :: value_type' để bạn có thể sử dụng mẫu của mình với ví dụ: con trỏ thô. – ecatmur

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