Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:cpp:高级技巧2

C++高级技巧2

模板、联合


// Generated by AI
// g++ --std=c++17 -Wall main.cpp
 
#include <algorithm>
#include <iostream>
#include <cstddef>  // std::ptrdiff_t
 
// 1: 指针差值
// 普通的 int 可能不足以表示大数组中的指针差值(特别是在64位系统上)。
// ptrdiff_t 被定义为能够安全容纳任何两个指针之间的差值的类型。
namespace ptrdiff {
 
inline void test() {
    int arr[] = {10, 20, 30, 40, 50};
 
    int* p1 = &arr[1];  // 指向20
    int* p2 = &arr[4];  // 指向50
 
    std::ptrdiff_t diff = p2 - p1;
 
    std::cout << "差值是: " << diff << std::endl;  // 输出: 3
}
 
} // namespace ptrdiff
 
// 2: 通用get
// 从某些容器类型(比如 std::tuple 或 std::pair)中获取第 N 个元素。
namespace generic_get {
 
inline void test() {
    std::tuple<int, double, std::string> t(42, 3.14, "hello");
 
    // std::get<N>(...) 是 编译期索引:N 是编译时常量(constexpr),不能用变量替代。
    int i = std::get<0>(t);        // 获取第一个元素,int
    double d = std::get<1>(t);     // 获取第二个元素,double
    std::string s = std::get<2>(t);// 获取第三个元素,string
 
    std::cout << i << ", " << d << ", " << s << std::endl;
}
 
} // namespace generic_get
 
// 3: 联合的STL实现
// 类似于 union 但能存储任意复杂类型,并正确调用构造/析构函数。
namespace stl_union {
 
inline void test() {
    std::variant<int, std::string> payload;
 
    payload = 42;              // 存储一个 int
    std::cout << std::get<int>(payload) << std::endl;
 
    payload = std::string("Hello");
    std::cout << std::get<std::string>(payload) << std::endl;
 
    // 判断当前存储的是哪种类型:
    if (std::holds_alternative<int>(payload)) {
        std::cout << "payload holds int: " << std::get<int>(payload) << std::endl;
    }
 
    // 使用 std::visit 进行访问(类似模式匹配):
    // ::std::visit 是 C++17 引入的一个函数,用于访问 std::variant 中当前持有的值。
    // 它的作用相当于对 variant 进行类型安全的模式匹配(type-safe pattern matching)。
    // std::visit 会根据 variant 当前存储的类型,自动调用你提供的函数或 lambda 表达式。
    // std::visit(visitor, variant);
    std::visit([](auto&& value) {
        std::cout << "payload holds: " << value << std::endl;
    }, payload);
 
    // index返回的是当前hold的类型的ID,T1对应的就是0
    std::cout << payload.index() << std::endl;
    if (payload.index() != std::variant_npos) {
        // 安全访问
    }
}
 
} // namespace stl_union
 
int main() {
    ptrdiff::test();
    generic_get::test();
    stl_union::test();
    return 0;
}
/var/www/DokuWikiStick/dokuwiki/data/pages/程序/cpp/高级技巧2.txt · Last modified: 2025/07/12 15:13 by zhonghui