2017-01-13 12 views
1

Предполагая, что у меня есть std::array<SomeType, N>, и я бы хотел вызвать функцию, которая использует итераторы для работы с объектами в std::array, но не зная о контейнере, который является std::array.Функция с использованием итераторов для выполнения операции объекта

SomeType класс, который имеет функцию DoSomething публичную()

Например, функция может быть:

template<typename Iterator> 
void action(Iterator &beg, Iterator &end) { 
    for (; beg != end; ++beg) 
    beg->doSomething(); 
} 

Вызов этой функции можно с помощью:

int main() { 
    std::array<SomeType, 10> a; 

    action<std::array<SomeType, 10>::iterator>(a.begin(), a.end()); 
} 

Но Мне интересно, так ли это? Тем более, что шаблон может использоваться для каждого класса. Есть ли способ ограничить функцию SomeType, не позволяя функции знать, что контейнер является std::array?

+0

Код в письменном виде не компилируется. По крайней мере, это не хорошо сформированный C++. [Demo] (http://melpon.org/wandbox/permlink/tw8f7mpNxZTZel9X) –

ответ

5
  1. Исправить ваш код: Вам не требуются аргументы lvalue. Фактически, итераторы предназначены для эффективного копирования.

    template<typename Iterator> 
    void action(Iterator beg, Iterator end) 
    //   ^^^^^^^^^^^^ ^^^^^^^^^^^^ 
    
  2. Пусть аргумент шаблона вычет делать свою работу:

    action(a.begin(), a.end()); 
    
+0

[Demo] (http://melpon.org/wandbox/permlink/IftDha8EQMpKdWhi) –

0

Обратите внимание, что стандартная библиотека уже имеет целый ряд алгоритмов, которые охватывают общий случай «делает то же самое по некоторым диапазон в некотором контейнере ":

#include <array> 
#include <vector> 
#include <algorithm> 
#include <numeric> 
#include <iterator> 

struct SomeType 
{ 
    void doSomething(); 

    SomeType mutatedCopy() const; 

    int someValue() const; 
}; 

int add_value(int i, const SomeType& st) { 
    return i + st.someValue(); 
} 

void call_something(SomeType& st) { st.doSomething(); } 
auto mutate_copy(SomeType const& st) { return st.mutatedCopy(); } 

int main() { 
    std::array<SomeType, 10> a; 
    std::vector<SomeType> b; 

    std::for_each(a.begin(), a.end(), call_something); 
    std::for_each(b.begin(), b.end(), call_something); 

    std::transform(a.begin(), a.end(), a.begin(), mutate_copy); 
    std::transform(b.begin(), b.end(), b.begin(), mutate_copy); 

    auto tot = std::accumulate(a.begin(), a.end(), 0, add_value) 
      + std::accumulate(b.begin(), b.end(), 0, add_value); 

    // you can even transform into dissimilar containers: 

    std::transform(a.begin(), a.end(), std::back_inserter(b), mutate_copy); 

}