通用 lambdas
Version >= C++ 14
Lambda 函式可以接受任意型別的引數。這允許 lambda 更通用:
auto twice = [](auto x){ return x+x; };
int i = twice(2); // i == 4
std::string s = twice("hello"); // s == "hellohello"
這是通過使閉包型別的 operator() 過載為模板函式在 C++中實現的。以下型別與上述 lambda 閉包具有相同的行為:
struct _unique_lambda_type
{
  template<typename T>
  auto operator() (T x) const {return x + x;}
};
並非通用 lambda 中的所有引數都必須是通用的:
[](auto x, int y) {return x + y;}
這裡,x 是基於第一個函式引數推匯出來的,而 y 將永遠是 int。
通用 lambda 也可以通過引用獲取引數,使用 auto 和 & 的通常規則。如果將泛型引數視為 auto&&,則這是對傳入引數的轉發引用 ,而不是右值引用 :
auto lamb1 = [](int &&x) {return x + 5;};
auto lamb2 = [](auto &&x) {return x + 5;};
int x = 10;
lamb1(x); // Illegal; must use `std::move(x)` for `int&&` parameters.
lamb2(x); // Legal; the type of `x` is deduced as `int&`.
Lambda 函式可以是可變引數並完美地轉發它們的引數:
auto lam = [](auto&&... args){return f(std::forward<decltype(args)>(args)...);};
要麼:
auto lam = [](auto&&... args){return f(decltype(args)(args)...);};
只適用於 auto&& 型別的變數正常工作。
使用泛型 lambda 的一個強有力的理由是訪問語法。
boost::variant<int, double> value;
apply_visitor(value, [&](auto&& e){
  std::cout << e;
});
在這裡,我們以多型的方式訪問; 但在其他情況下,我們傳遞的型別的名稱並不有趣:
mutex_wrapped<std::ostream&> os = std::cout;
os.write([&](auto&& os){
  os << "hello world\n";
});
重複 std::ostream& 的型別就是這裡的噪音; 每次使用它時都必須提到變數的型別。在這裡,我們建立了一個訪問者,但沒有多型的訪問者; 使用 auto 的原因與你在 for(:) 迴圈中使用 auto 的原因相同。