当前位置: 首页 > article >正文

深入理解C++23的Deducing this特性(下):高级应用与实战技巧

1. 高级应用场景

1.1 设计模式实现优化

1.1.1 Builder模式

传统实现:

class Builder {
    std::string str_;
    int num_;
public:
    Builder& setString(std::string s) & {
        str_ = std::move(s);
        return *this;
    }
    Builder&& setString(std::string s) && {
        str_ = std::move(s);
        return std::move(*this);
    }
    Builder& setNumber(int n) & {
        num_ = n;
        return *this;
    }
    Builder&& setNumber(int n) && {
        num_ = n;
        return std::move(*this);
    }
};

使用Deducing this的实现:

class Builder {
    std::string str_;
    int num_;
public:
    template<typename Self>
    decltype(auto) setString(this Self&& self, std::string s) {
        self.str_ = std::move(s);
        return std::forward<Self>(self);
    }
    
    template<typename Self>
    decltype(auto) setNumber(this Self&& self, int n) {
        self.num_ = n;
        return std::forward<Self>(self);
    }
};
1.1.2 访问者模式
// 基础组件
struct Component {
    template<typename Self, typename Visitor>
    decltype(auto) accept(this Self&& self, Visitor&& visitor) {
        return std::forward<Visitor>(visitor)(std::forward<Self>(self));
    }
};

// 具体组件
struct ConcreteComponent : Component {
    int data = 42;
};

// 访问者
struct Visitor {
    void operator()(const Component& c) {
        std::cout << "访问基础组件" << std::endl;
    }
    
    void operator()(const ConcreteComponent& c) {
        std::cout << "访问具体组件,数据:" << c.data << std::endl;
    }
};

1.2 与协程的结合使用

class AsyncOperation {
public:
    template<typename Self>
    auto start(this Self&& self) -> std::future<void> {
        co_await std::async(std::launch::async, [self = std::forward<Self>(self)]() {
            // 异步操作
        });
    }
    
    template<typename Self>
    auto with_timeout(this Self&& self, std::chrono::milliseconds timeout) 
        -> std::future<bool> {
        auto future = self.start();
        
        if (future.wait_for(timeout) == std::future_status::timeout) {
            co_return false;
        }
        co_return true;
    }
};

1.3 CRTP进阶应用

// 基础混入类
template<typename Derived>
class Comparable {
public:
    template<typename Self, typename Other>
    bool less_than(this Self&& self, Other&& other) const {
        return static_cast<const Derived&>(self).compare(other) < 0;
    }
    
    template<typename Self, typename Other>
    bool greater_than(this Self&& self, Other&& other) const {
        return static_cast<const Derived&>(self).compare(other) > 0;
    }
    
    template<typename Self, typename Other>
    bool equals(this Self&& self, Other&& other) const {
        return static_cast<const Derived&>(self).compare(other) == 0;
    }
};

// 使用示例
class String : public Comparable<String> {
    std::string data_;
public:
    explicit String(std::string s) : data_(std::move(s)) {}
    
    int compare(const String& other) const {
        return data_.compare(other.data_);
    }
};

2. 模板元编程技巧

2.1 类型特征与概念

// 检查类型是否支持特定操作
template<typename T>
concept HasToString = requires(T t) {
    { t.toString() } -> std::convertible_to<std::string>;
};

class StringConverter {
public:
    template<typename Self>
        requires HasToString<std::remove_reference_t<Self>>
    std::string convert(this Self&& self) {
        return self.toString();
    }
    
    // 回退版本
    template<typename Self>
    std::string convert(this Self&& self) {
        return "Conversion not supported";
    }
};

2.2 完美转发与值类别保持

class PerfectForwarder {
public:
    template<typename Self, typename... Args>
    decltype(auto) forward_to_impl(this Self&& self, Args&&... args) {
        if constexpr (std::is_lvalue_reference_v<Self>) {
            return self.implementation(std::forward<Args>(args)...);
        } else {
            return std::move(self).implementation(std::forward<Args>(args)...);
        }
    }
    
private:
    template<typename... Args>
    auto implementation(Args&&... args) & {
        std::cout << "左值版本" << std::endl;
        return process(std::forward<Args>(args)...);
    }
    
    template<typename... Args>
    auto implementation(Args&&... args) && {
        std::cout << "右值版本" << std::endl;
        return process(std::forward<Args>(args)...);
    }
    
    template<typename... Args>
    auto process(Args&&... args) {
        // 实际处理逻辑
        return sizeof...(args);
    }
};

3. 实际项目中的应用

3.1 智能指针包装器

template<typename T>
class SmartWrapper {
    std::shared_ptr<T> ptr_;
    
public:
    explicit SmartWrapper(T* ptr) : ptr_(ptr) {}
    
    template<typename Self>
    auto get_pointer(this Self&& self) {
        if constexpr (std::is_const_v<std::remove_reference_t<Self>>) {
            return static_cast<const T*>(self.ptr_.get());
        } else {
            return self.ptr_.get();
        }
    }
    
    template<typename Self, typename F>
    auto with_lock(this Self&& self, F&& func) {
        std::lock_guard<std::mutex> lock(self.mutex_);
        return std::forward<F>(func)(self.get_pointer());
    }
    
private:
    std::mutex mutex_;
};

3.2 线程安全容器

template<typename T>
class ThreadSafeContainer {
    std::vector<T> data_;
    mutable std::shared_mutex mutex_;
    
public:
    template<typename Self>
    auto read(this Self&& self) const {
        std::shared_lock lock(self.mutex_);
        return self.data_;
    }
    
    template<typename Self, typename U>
    void write(this Self&& self, U&& value) {
        std::unique_lock lock(self.mutex_);
        self.data_.push_back(std::forward<U>(value));
    }
    
    template<typename Self, typename Pred>
    auto find_if(this Self&& self, Pred&& pred) const {
        std::shared_lock lock(self.mutex_);
        return std::find_if(self.data_.begin(), 
                          self.data_.end(),
                          std::forward<Pred>(pred));
    }
};

4. 性能优化技巧

4.1 移动语义优化

class ResourceManager {
    std::vector<std::unique_ptr<Resource>> resources_;
    
public:
    template<typename Self>
    auto acquire_resource(this Self&& self) {
        if constexpr (std::is_rvalue_reference_v<Self&&>) {
            // 对于右值对象,可以直接移动资源
            return std::move(self.resources_.back());
        } else {
            // 对于左值对象,需要克隆资源
            return std::make_unique<Resource>(*self.resources_.back());
        }
    }
};

4.2 内存分配优化

class MemoryOptimizer {
    std::vector<char> buffer_;
    
public:
    template<typename Self, typename T>
    T* allocate(this Self&& self, std::size_t count = 1) {
        std::size_t required = count * sizeof(T);
        if (self.buffer_.size() < required) {
            if constexpr (std::is_rvalue_reference_v<Self&&>) {
                // 右值对象可以重用buffer
                self.buffer_.resize(required);
            } else {
                // 左值对象需要重新分配
                self.buffer_ = std::vector<char>(required);
            }
        }
        return reinterpret_cast<T*>(self.buffer_.data());
    }
};

5. 调试与测试策略

5.1 类型检查与断言

class DebugHelper {
public:
    template<typename Self>
    void debug_info(this Self&& self) {
        // 输出类型信息
        std::cout << "对象类型: " << typeid(Self).name() << std::endl;
        
        // 检查const限定符
        if constexpr (std::is_const_v<std::remove_reference_t<Self>>) {
            std::cout << "const对象" << std::endl;
        }
        
        // 检查值类别
        if constexpr (std::is_rvalue_reference_v<Self&&>) {
            std::cout << "右值对象" << std::endl;
        } else {
            std::cout << "左值对象" << std::endl;
        }
        
        // 检查是否可移动
        if constexpr (std::is_move_constructible_v<
            std::remove_reference_t<Self>>) {
            std::cout << "可移动对象" << std::endl;
        }
    }
};

5.2 单元测试策略

class TestSubject {
public:
    template<typename Self>
    bool test_method(this Self&& self) {
        // 使用static_assert进行编译期检查
        static_assert(std::is_same_v<
            std::remove_cvref_t<Self>,
            TestSubject
        >, "类型不匹配");
        
        // 运行时检查
        assert(self.validate());
        
        return true;
    }
    
private:
    bool validate() const { return true; }
};

// 测试用例
void run_tests() {
    TestSubject subject;
    const TestSubject const_subject;
    
    // 测试左值
    assert(subject.test_method());
    
    // 测试const左值
    assert(const_subject.test_method());
    
    // 测试右值
    assert(TestSubject{}.test_method());
}

参考资料

[1] P0847R7: Deducing this
[2] C++23 Standard
[3] CppCon 2021: “The C++23 this parameter” - Gašper Ažman
[4] C++ Reference: Member Functions
[5] Modern C++ Design Patterns
[6] Effective Modern C++


http://www.kler.cn/a/450595.html

相关文章:

  • clickhouse复现修复 结构需要清理 错误 structure need clean
  • QT的前景与互联网岗位发展
  • Spring常见面试题总结
  • 《Vue3实战教程》5:响应式基础
  • ArcGIS Pro 3.4新功能3:空间统计新特性,基于森林和增强分类与回归,过滤空间自相关
  • Windows内核开发环境配置
  • mapbox基础,加载mapbox官方地图
  • RGCL:A Review-aware Graph Contrastive Learning Framework for Recommendation
  • 自动驾驶系统研发系列—追尾风险不再隐形:解密后碰撞预警系统(RCW)的技术与应用
  • 交通控制系统中的 Prompt工程:引导LLMs实现高效交叉口管理 !
  • ensp 基于静态NAT发布公司网站服务器,
  • WebGL2示例项目常见问题解决方案
  • Wireshark时间设置介绍:时间格式、时间参考和时间平移
  • [Linux] Shell 命令及运行原理
  • 测开面经分享(偏Python)
  • 【双指针算法】--复写零
  • 编程新选择:深入了解仓颉语言的优雅与高效
  • 华为OD E卷(100分)32-字符串分割
  • C中设计不允许继承的类的实现方法是什么?
  • 一个简单的机器学习实战例程,使用Scikit-Learn库来完成一个常见的分类任务——**鸢尾花数据集(Iris Dataset)**的分类
  • Pion WebRTC 项目教程
  • 【JetPack】Navigation知识点总结
  • 【es6复习笔记】解构赋值(2)
  • 【算法】一维二维数组前缀和,以及计算二维矩阵中的子矩阵和
  • Docker-如何启动docker
  • 使用Python开发PPT图片提取与九宫格合并工具