【问题标题】:Do every operation twice每个操作做两次
【发布时间】:2018-04-11 12:14:07
【问题描述】:

我希望每个函数都执行两次。参数在数组中,所以它是这样的:

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]);

在这种情况下,顺序很重要。

【问题讨论】:

  • 不,无法自动执行此操作。但也许你的代码需要重构。
  • 你喜欢哪种语法? foo({&amp;fun1, &amp;fun2, &amp;fun3}, {A[0], A[1]}); 之类的东西?
  • for (auto f : {&amp;func1, &amp;func2, &amp;func3}) { for (auto&amp; a : {A[0], A[1]}) { f(a); } } ?
  • 函数的签名是否相同?
  • @MichaelWalz 隐式转换可能正在发生。

标签: c++ arrays for-loop


【解决方案1】:

您可以使用函数指针来循环遍历要在容器中的每个元素上调用的所有函数。例如

#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);
        }
    }
}

Output

fun1: 2
fun1: 5
fun2: 2
fun2: 5

【讨论】:

    【解决方案2】:

    这是一个用于存储函数数组的 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”)很多
    • 我想说一个 C 版本(显然忽略了std)。我刚刚编辑了它,谢谢!
    • 如果 OP 故意标记 C++,提供 C 解决方案的目的是什么?
    【解决方案3】:

    您可以将该行为包装在一个高阶函数中,该函数将一个函数应用两次并将该函数应用于您的函数。

    使用 C++17 折叠表达式,该函数看起来很简单

    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]);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-13
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多