C++ function

简单记录下编写代码时遇到的问题:

在调用一个接口的时候,需要传入一个std::function类型的参数。

之前在调用此接口时传入的参数lambda表达式类型。由于接口的定义为function<void()>类型,而在调用传入参数时,需要遍历数组,处理数组中的成员。若采用lambda的方式,只能通过捕获的方式传值,考虑到作用域和lambda之间的干扰,应采用值捕获的方式。代码看起来像这样:

复制代码
void deal(const function<void()>& func) {
    func();
}
int main(int argc, char* argv[]) {
    vector<int> nums = { 1,2,3,4 };   
    for (auto num:nums) {
        auto func = [num]() {
            cout << num << endl;
        };
        deal(func);
    }
    return 0;
}
复制代码

实际的处理func处理过程很复杂,将lambda表达式在for循环中定义,代码段过长。而且此函数是多次定时调用,涉及到内存分配, 采用lambda需要每次重新分配内存,每次使用完之后释放,效率较低。

改为使用仿函数,则代码如下:

复制代码
class A {
public:
    A(int num):_num(num) {}
    void operator()() {
        std::cout << _num << std::endl;
    }
private:
    int _num;
};

void deal(const function<void()>& func) {
    func();
}
int main(int argc, char* argv[]) {
    vector<int> nums = { 1,2,3,4,5,6 };   
    for (auto num:nums)
    {
        A a(num);
        deal(a);
    }
    return 0;
}
复制代码

需要注意的是:

在构造function时,会对仿函数进行拷贝构造和移动构造,在VS2019中的实现如下:

    template <class _Fx, typename _Mybase::template _Enable_if_callable_t<_Fx&, function> = 0>
#else // ^^^ _USE_FUNCTION_INT_0_SFINAE // !_USE_FUNCTION_INT_0_SFINAE vvv
    template <class _Fx, class = typename _Mybase::template _Enable_if_callable_t<_Fx&, function>>
#endif // _USE_FUNCTION_INT_0_SFINAE
    function(_Fx _Func) {
        this->_Reset(_STD move(_Func));
    }

即:在构造function时,先按值传递仿函数对象,调用一次拷贝构造函数,在function函数内部再调用移动构造函数。实现仿函数时,若涉及到内存申请释放,应自定义拷贝构造函数和移动构造函数,避免浅拷贝引起的问题。

编译器默认生成的拷贝构造函数和移动构造函数相关问题参见:

https://www.cnblogs.com/yajiu/articles/15435277.html

 

posted @   亚九  阅读(393)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示