// ===== CodeLab: C++14 新特性:泛型 lambda、返回类型推导与变量模板 =====
// 来源: https://aoerliang.dpdns.org/articles/cpp14-features
// 以下代码片段按文章出现顺序拼接, 共 5 段

// ----- 片段 1 (cpp) -----
#include <iostream>

int main() {
    auto square = [](auto x) { return x * x; };

    std::cout << square(5) << std::endl;      // int:25
    std::cout << square(2.5) << std::endl;    // double:6.25
    std::cout << square(3.0f) << std::endl;   // float:9
    return 0;
}

// ----- 片段 2 (cpp) -----
#include <iostream>
#include <vector>

// C++11 要写:auto add(int a, int b) -> int
auto add(int a, int b) {
    return a + b;   // 自动推导为 int
}

// decltype(auto):保留引用的返回类型
decltype(auto) first(std::vector<int>& v) {
    return v[0];    // 返回 int&,可写回
}

int main() {
    std::vector<int> v = {10, 20, 30};
    first(v) = 99;
    std::cout << add(1, 2) << std::endl;      // 3
    std::cout << v[0] << std::endl;           // 99
    return 0;
}

// ----- 片段 3 (cpp) -----
#include <iostream>

template <typename T>
constexpr T pi = T(3.1415926535897932385);

int main() {
    std::cout << pi<double> << std::endl;   // 双精度圆周率
    std::cout << pi<float> << std::endl;    // 单精度圆周率
    std::cout << pi<int> << std::endl;      // 整型截断为 3
    return 0;
}

// ----- 片段 4 (cpp) -----
#include <iostream>
#include <memory>

// C++14 起 constexpr 函数可以有循环和局部变量
constexpr int factorial(int n) {
    int result = 1;
    for (int i = 2; i <= n; ++i) {
        result *= i;
    }
    return result;
}
static_assert(factorial(5) == 120, "5! 应为 120");

int main() {
    auto p = std::make_unique<int[]>(4);   // 分配 4 个 int
    p[0] = 42;

    constexpr auto million = 1'000'000;    // 数字分隔符
    constexpr auto mask = 0b1010'1100;     // 二进制字面量
    std::cout << p[0] << ' ' << million << ' ' << mask << std::endl;
    return 0;
}

// ----- 片段 5 (cpp) -----
# 编译并运行
g++ -std=c++14 main.cpp -o main
./main

clang++ -std=c++14 main.cpp -o main
