Делайте каждую операцию дважды

Я бы хотел, чтобы каждую функцию выполняли дважды. Аргументы находятся в массиве, поэтому это примерно так:

fun1(A[0]);
fun1(A[1]);

fun2(A[0]);
fun2(A[1]);

fun3(A[0]);
fun3(A[1]);

Есть ли способ сделать это автоматически? Я не могу использовать

for(int i=0; i<2; i++)

потому что это будет:

fun1(A[0]);
fun2(A[0]);
fun3(A[0]);

fun1(A[1]);
fun2(A[1]);
fun3(A[1]);

И порядок в этом случае имеет значение.

Можете ли вы переписать свои функции?

Petar Velev 11.04.2018 14:16

Нет, это невозможно сделать автоматически. Но, возможно, ваш код нужно реорганизовать.

Jabberwocky 11.04.2018 14:16

Три шлейфа for?

Tripp Kinetics 11.04.2018 14:16

Какой синтаксис тебе нравится? что-то вроде foo({&fun1, &fun2, &fun3}, {A[0], A[1]});?

Jarod42 11.04.2018 14:17
for (auto f : {&func1, &func2, &func3}) { for (auto& a : {A[0], A[1]}) { f(a); } }?
Jarod42 11.04.2018 14:19

У функций одинаковые подписи?

Galik 11.04.2018 14:24

@Galik, очевидно, fun1, fun2 и fun3 имеют одинаковую подпись, иначе первый фрагмент кода был недействителен.

Jabberwocky 11.04.2018 14:28

@MichaelWalz Первый фрагмент кода - это просто пример кода. Поэтому я хотел знать, был ли реальный код строго идентичными подписями. Но даже пример кода может смешивать совместимые типы параметров.

Galik 11.04.2018 14:34

Могут происходить неявные преобразования @MichaelWalz.

Quentin 11.04.2018 14:36

Подпись @MichaelWalz может иметь значения по умолчанию, которых нет во фрагменте

463035818_is_not_a_number 11.04.2018 14:41
0
10
85
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

#include <iostream>
#include <vector>

void fun1(int i)
{
    std::cout << "fun1: " << i << "\n";
}

void fun2(int i)
{
    std::cout << "fun2: " << i << "\n";
}

int main()
{
    using fn_t = void(*)(int);
    std::vector<fn_t> funs{&fun1, &fun2};
    std::vector<int> A = {2, 5};

    for (auto& f : funs)
    {
        for (int i : A)
        {
            f(i);
        }
    }
}

Выход

fun1: 2
fun1: 5
fun2: 2
fun2: 5
Ответ принят как подходящий

Вот версия C (без учета пространства имен std) для хранения массива функций, на всякий случай, если вы не можете использовать решение, предоставленное @CoryKramer.

typedef void (*PointerFunction)(int x);

void functA(int a) {
    std::cout << "functA: " << a << std::endl;
}
void functB(int b) {
    std::cout << "functB: " << b << std::endl;
}

PointerFunction functions[] = { functA, functB };

for (int func = 0; func < 2; func++) {
    for (int i = 0; i < 2; i++) {
        functions[func](i);
    }
}
std::vector предшествует C++ 11 (при условии, что вы имели в виду под "C++ 0x") во многом
UnholySheep 11.04.2018 14:34

Я хотел сказать версию C (явно игнорируя std). Я только что отредактировал его, спасибо!

Neo 11.04.2018 14:39

Если OP намеренно пометил C++, какова цель предоставления решения C?

Cory Kramer 11.04.2018 14:47

Вы можете обернуть это поведение в функцию более высокого порядка, которая применяет функцию дважды, и применять эту функцию к вашим функциям.

Используя 17-кратные выражения C++, эта функция может выглядеть так же просто, как

template <typename Func, typename Arr, typename... Indices>
void map_indices(Func&& f, Arr&& arr, Indices&&... is) {
  (f(arr[is]), ...);
}

Используя C++ 11 или C++ 14, это можно реализовать с помощью рекурсии.

Тогда ваш пример будет выглядеть так

#include <array>
#include <iostream>

template <typename Func, typename Arr, typename... Indices>
void map_indices(Func&& f, Arr&& arr, Indices&&... is) {
  (f(arr[is]), ...);
}

void f1(int x) {
  std::cout << "f1 " << x << '\n';
}

void f2(int x) {
  std::cout << "f2 " << x << '\n';
}

void f3(int x) {
  std::cout << "f3 " << x << '\n';
}

int main() {
  std::array arr{1, 2, 3};
  map_indices(f1, arr, 0, 1);
  map_indices(f2, arr, 0, 1);
  map_indices(f3, arr, 0, 1);
}

Если вы знаете, что вам понадобятся только индексы 0 и 1, map_indices можно упростить до

template <typename Func, typename Arr>
void map_indices(Func&& f, Arr&& arr) {
  f(arr[0]);
  f(arr[1]);
}

Другие вопросы по теме