c ++, выполнять функцию на каждом члене массива - PullRequest
1 голос
/ 17 ноября 2011

У меня есть вопрос относительно c ++ и массивов.

скажем, у меня есть класс, который называется CustomArray, и это не что иное, как универсальный массив, который имеет атрибуты для размера и емкости, чтобы сделать массив динамическим.определяется как:

template<typename T>
class CustomArray
{
public:
    int capacity, size;
    T* items;
    //constructor

    //destructor

    //function1

    //function2

    //etc...
};

Теперь я немного застрял, я хочу реализовать такую ​​функцию: "

void performOnAllItems(/*function?*/)
{
    for(int i = 0; i < size; i++)
    {
        //perform function on element
    }
}

, которая принимает в качестве параметра другую функцию (если это возможно?) и выполняет его на всех элементах. возможно ли это? и если да ... как?

заранее спасибо.

Ответы [ 3 ]

9 голосов
/ 17 ноября 2011

Добавить членов begin и end примерно так:

T *begin() { return items; }

T *end() { return items + size; }

Создать функтор, производный от std::unary_function.

Например,

template <typename T>
class MyFunc : std::unary_function<T, void> {
public:
    void operator()(T& t) {
    // ...
    }
};

Затем позвоните std::foreach(foo.begin(), foo.end(), MyFunc);

Обновление

В C ++ 11 вы можете использовать лямбду для foreach:

std::foreach(foo.begin(), foo.end(),
              [/* (1) */](T& t) { /* ... */ }
            ); 

Если (1) не пусто, тогда лямбда - это закрытие;это называется захватом лямбда-выражений, и Visual C ++ 10 лямбда-выражений предоставляет хороший пример этого.

6 голосов
/ 17 ноября 2011
template<class functionptr>
void performOnAllItems(functionptr ptr)
{
    for(int i = 0; i < size; i++)
        ptr(items[i]);
}

или

typedef void (*functionptr)(T&);
void performOnAllItems(functionptr ptr)
{
    for(int i = 0; i < size; i++)
        ptr(items[i]);
}

Второй параметр сильно ограничивает возможности использования, однако первый - нет.

1 голос
/ 17 ноября 2011

Конечно.Вам просто нужно изменить performOnAllItems, чтобы получить указатель на функцию, которая возвращает void и принимает в качестве параметра либо T, либо указатель на T (согласно моему решению ниже), который вызывает указатель на функцию для каждого элемента всписок.

template <typename T>
void CustomArray::performOnAllItems(void (*action)(T*))
{
    for(int i = 0; i < size; i++)
    {
        action(items + i);
    }
}
...