C++ 如何在运行时向函数传递 N 个参数

问题描述 投票:0回答:1

我尝试实现一个采用以下参数的函数

template <FUNC>
compute_in_D_dims(int D, FUNC f, int N)

哪里

  • D 是维数
  • f 是一个提供的函数,它将接受 D 个参数 f(x_1, ..., x_D) 并返回一个 double
  • N 是序列 0, ..., N-1 的上限

我希望为序列 0 到 N-1 中的 D 个数字创建具有重复的排列

所以当 D = 3 时,它看起来像

for (int i = 0; i < N; ++i)
    for (int j = 0; j < N; ++j)
       for (int k = 0; k < N; ++k)
           f(i, j, k)

现在 D 作为参数提供,并且是先验未知的 。此外,D 可能很大,这使得深度嵌套循环的编写不太可行。

我的想法是,对于排列,存在到数字 I 的双射映射,因为我有 N^D 个排列,并且我可以对它们进行计数。

回到我的示例,D = 3,N = 2,我的排列如下

0 0 0
0 0 1
0 1 0
1 1 1
1 0 0
1 0 1

bijection(n) = // implement function

将返回第 5 个索引(从 0 开始计数)

bijection(5) = {1, 0, 1}

现在是最困难的部分:

如何将返回元组/向量/...传递给提供的函数?

它可能是 2 个元素或 10 个元素,我对如何将 D-many 参数传递给函数一无所知。此外,由于函数作为参数给出,我无法控制它。

我听说过“可变参数函数”的提示,但我对它到底是什么以及如何开始一无所知。

c++ parameter-passing variadic-functions
1个回答
0
投票

你不需要一个可变参数函数。据我所知,可变参数函数是接受 n 个参数并相应地使用它们的函数。它们有助于管理手动制作时有些(会变得)混乱的代码。

现在,对于答案,我之前在练习 C++ 和排列时也做过同样的事情,我发现,你不需要可变数量的循环。相反,您可以只计算将会出现的排列数量

 P(n,r)= 1*2*...*n
。这将告诉您需要为排列值进行多少次循环。然后,您可以初始化大小为 D 的 int 向量并用 0 填充它(因为第一个值为 0,0,0)。在下一个循环中,您可以像这样调用函数
f

std::vector<int> indices(D, 0); //filling the vector with size D with only 0's
f(indices[0], indices[1], indices[2]); 

然后您可以根据

N
的值更新这三个值。喜欢:

 for (int j = D - 1; j >= 0; --j) {
            indices[j]++;
            if (indices[j] < N)
                break;
            indices[j] = 0;
        }

因此,总共只有 3 个 for 循环,一个用于计算排列数量,第二个用于调用函数,第三个(这是第二个循环的嵌套循环)更新索引。

我根据你的函数想法制作的函数:

template <typename FUNC>
void compute_in_D_dims(int D, FUNC f, int N) {
    std::vector<int> indices(D, 0); 
    
    int total_permutations = 1;
    for (int i = 0; i < D; ++i)
        total_permutations *= N; 

    for (int i = 0; i < total_permutations; ++i) {
        f(indices[0], indices[1], indices[2]); 
        
        for (int j = D - 1; j >= 0; --j) {
            indices[j]++;
            if (indices[j] < N)
                break;
            indices[j] = 0;
        }
    }
}

我希望这有帮助!这对我有用。告诉我它是否适合你。

编辑:

我认为我误解了这个问题,并以硬编码的方式做到了这一点,正如@Fareanor 所指出的。

您可以修改函数 f ,使其接受 int 向量,而不是 D 个参数。

喜欢:

 for (int i = 0; i < total_permutations; ++i) {
        f(indices); 
//the rest of the code
}

这样,你就可以这样做:

//assuming your function prints the args
void f(std::vector<int> indices)
{
    for(auto id:indices)
    {
        std::cout<< id<<" ";
    }
    std::cout<<std::endl;//for the next permutation
}
© www.soinside.com 2019 - 2024. All rights reserved.