2016-12-21 2 views
9

У меня есть объект с функциями для получения начальной и конечной итераторы:Как создать диапазон от итератора начала и конца?

const_iterator err_begin() const 
const_iterator err_end() const 

Потому что они не по имени begin и end, я не могу передать свой объект непосредственно к функциям в диапазоне-v3.

Есть ли простая обертка, которую я могу использовать, чтобы этот объект работал с библиотекой range-v3?

Например:

auto hasErrors = !empty(something(x.err_begin(), x.err_end())); 
+0

Добавьте 'begin()' и 'end()' которые называют эти две функции соответственно? –

+0

Объект является частью библиотеки. Я не могу изменить имена методов или добавлять новые методы. – sdgfsdh

+0

Создайте простую оболочку, о которой вы говорите, которая отображает начальные и конечные вызовы на нужные вам. – mascoj

ответ

9

Похоже, что вы ищете iterator_range:

auto hasErrors = !empty(ranges::make_iterator_range(x.err_begin(), x.err_end())); 
+4

Документация для 'iterator_range' живет [здесь] (https://ericniebler.github.io/range-v3/structranges_1_1v3_1_1iterator__range.html). Просто вызовите 'диапазоны :: make_iterator_range (x.err_begin(), x.err_end())'. –

+0

Я больше не могу найти 'iterator_range' и' make_iterator_range' из кода. Они были переименованы? – kaba

4

Вы уточнили, что класс в вопросе является частью библиотеки, которую вы не можете изменить. Хорошо. Создать класс фасада:

class FacadeClass { 

     const RealClassWithErrBeginEnd &r; 

public: 

     FacadeClass(const RealClassWithErrBeginEnd &r) : r(r) {} 

     auto begin() const { return r.err_begin(); } 
     auto end() const { return r.err_end(); } 
}; 

Это должно быть достаточно хорошим, чтобы обмануть большинство кода, ожидающего контейнер. В худшем случае, вы, возможно, потребуется предоставить дополнительные определений типов на фасаде, т.е. value_type и т.д ...

+0

Этот тип не [Regular] (http://stackoverflow.com/a/14000046/195873). Он не будет хорошо воспроизводиться с остальной библиотекой range-v3. Ответ Брайана ниже - правильный ответ. (Я автор range-v3, FWIW.) –

0

boost::make_iterator_range будет делать правильные вещи. Теперь добавьте немного ADL, и мы обнаружим, что одна свободная функция решает все наши проблемы:

#include <vector> 
#include <iostream> 
#include <string> 
#include <boost/range.hpp> 


// simulate the library class 
struct X 
{ 
    auto err_begin() const { return errors.begin(); } 
    auto err_end() const { return errors.end(); } 

    std::vector<std::string> errors; 

}; 

// provide a generator to build an iterator range 
auto errors(const X& x) 
{ 
    return boost::make_iterator_range(x.err_begin(), x.err_end()); 
} 

// do things with the iterator_range 
int main() 
{ 
    X x; 
    for (const auto& err : errors(x)) 
    { 
     std::cout << err << std::endl; 
    } 

    std::cout << empty(errors(x)) << std::endl; 
} 
Смежные вопросы