深入理解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++