c++ - 如何在 C++ 中将函数作为可选参数传递?

标签 c++

我有两个非常相似的函数,所以我正在尝试减少代码重复。我认为我可以创建一个新函数 MyFunction() 调用,无论有没有 func 都可以选择应用于参数。因此,func 的默认值应该是一个仅返回 i 的函数。我不确定我的代码是否正确,也无法找到如何定义默认函数。我有这样的东西(注释掉 MyFunction 来运行代码)


#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>

int somefunc(int b, int i){
    return i-b; // simplified
}

std::vector<int> MyOldFunction1(const int a,
                            std::vector<int> list) {
          std::transform(list.begin(), list.end(), list.begin(), 
                      [a](int i) -> int {return a*i;});
       return list;
}

std::vector<int> MyOldFunction2(const int a,
                            std::vector<int> list,
                            const int b) {
          std::transform(list.begin(), list.end(), list.begin(), 
                      [a,b](int i) -> int {return a*somefunc(b,i);});
       return list;
}

// Suggested combination (not working)
std::vector<int> MyFunction(const int a,
                            std::vector<int> list, std::function<int,int> &f,
                            const int b) {
          std::transform(list.begin(), list.end(), list.begin(), 
                      [a,b](int i) -> int {return a*f(b,i);});
       return list;
}

void PrintVector(std::vector<int> a) {
    for(auto i=a.begin(); i!=a.end(); ++i){
        std::cout<<(*i);
    }
    std::cout<<std::endl;
}


int main () {
    int p[] = {1, 2, 3, 4, 5};
    std::vector<int> a(p, p+5);
    PrintVector(MyOldFunction1(1,a)); // 1,2,3,4,5
    PrintVector(MyOldFunction2(1,a,1)); // 0,1,2,3,4

}

有没有更有效/更干净的方法来做到这一点?如有任何建议,我们将不胜感激!

最佳答案

您可以拥有 std::function<int(int)> 类型的默认参数,例如

std::vector<int> MyFunction(const int a, 
                            std::vector<int> list, 
                            std::function<int(int)> func = [](int i) -> int { return i; }) {
    std::transform(list.begin(), list.end(), list.begin(), [a, func](int i) -> int { return a*func(i); });
   return list;    
}

然后您可以传递一个调用 somefunc 的 lambda与您的b ,例如

[b = 2](int i) -> int { return somefunc(b, i); }

See it on coliru

旁白:您需要删除 const来自参数list如果您打算在正文中修改它。

此外:使用 C++20,您可以对其进行模板化,并且仍然可以传达 func必须接受int并返回int :

template<typename Func = decltype([](int i) -> int { return i; })>
requires(std::is_invocable_r_v<int, Func, int>)
std::vector<int> MyFunction(const int a, 
                            std::vector<int> list, 
                            Func func = {}) {
    std::transform(list.begin(), list.end(), list.begin(), [a, func](int i) -> int { return a*func(i); });
   return list;    
}

关于c++ - 如何在 C++ 中将函数作为可选参数传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73458049/

相关文章:

c++ - 是否在非数组指针的末尾创建一个指针,该指针不是从 C++17 中的一元运算符和未定义行为派生的?

c++ - 将 char[] 转换为 off_t

c++ - 使用 Visual Studio 2008 构建 OpenCV 应用程序并从另一台计算机运行它

带有引用参数的 C++ 函数因迭代器而出错。求解释

c++ - 为什么构造函数调用异常后没有释放unique_ptr?

用于元编程的 C++ STL 函数等价物

c++ - QwtPlot鼠标点击事件

c++ - 无法理解 cv2::absdiff 的行为:c++

c++ - 使用 htonl() 使用 C++ 正确转换本地主机

c++ - 如何使用 7.1 音频系统 sfml 播放声音?