07 July 2022

C++ 核心指南目录

理由

函数不能捕获局部变量,也不能在局部范围。如果需要此类操作,尽可能使用 lambda,不然就写个函数对象。不过 lambda 和函数对象不能重载。如果需要重载,还是得写个函数(lambda 重载很麻烦)。如果两种方式都可以,就用函数吧。尽量使用最简单的工具。

例子

// -*- compile-command: "g++ -std=c++20 code.cpp && ./a"; -*-
#include <iostream>
#include <gsl/gsl>
using namespace std;
using namespace gsl;
// writing a function that should only take an int or a string
// -- overloading is natural
void f(int);
void f(const string&);

// writing a function object that needs to capture local state and appear
// at statement or expression scope -- a lambda is natural
using work = int;
vector<work> lots_of_work() {
    return vector<work>{1,2,3,4,5,6};
}
int main()
{
    vector<work> v = lots_of_work();
    for (int tasknum = 0; tasknum < max; ++tasknum) {
        pool.run([=, &v] {
            /*
              ...
              ... process 1 / max - th of v, the tasknum - th chunk
              ...
            */
        });
    }
    pool.join();
}

例外

用泛型 lambda 可以写出简洁的函数模板,所有有时候比普通函数模板编写效率更高。不过,不久以后普通函数也能有 Concept 参数的时候, 泛型 lambda 就无此优势了。

强化

在全局范围内把非泛型 lambda 赋值给变量的情况(如: auto x = [](int i) { ...; };) 应该给予警告。这时候应该用普通函数。