【C++】在使用PImpl技术时,template/typename的不常见用法
PImpl:Pointer to implementation,常用于隐藏实现细节,构造拥有稳定 ABI 的 C++ 库接口,及减少编译时依赖。
在使用pimpl技术时,pimpl是类静态变量,对其在源文件中的实现需要使用typename关键字
对于模板类的静态成员变量的定义,你需要使用完整的模板类型限定符来指定 std::unique_ptr
的类型。在这个示例中,我们使用 typename MyClass<T>::Impl
来指定 std::unique_ptr
的类型。
// MyClass.h
#include <memory>
template<typename T>
class MyClass {
public:
void doSomething();
private:
class Impl;
static std::unique_ptr<Impl> p_impl; // 静态 p_impl 变量的声明
};
// MyClass.cpp
template<typename T>
class MyClass<T>::Impl {
public:
void doSomething() {
// 实现具体逻辑
std::cout << "Doing something..." << std::endl;
}
};
template<typename T>
std::unique_ptr<typename MyClass<T>::Impl> MyClass<T>::p_impl = std::make_unique<typename MyClass<T>::Impl>(); // 静态 p_impl 变量的定义
template<typename T>
void MyClass<T>::doSomething() {
p_impl->doSomething();
}
如果一个模板类使用p_impl技术,同时内部包含模板函数,那么模板函数的调用需要额外使用template关键字
在最后的代码p_impl->template doSomething<U>();
处,使用template关键字告诉编译器我们正在引用一个模板成员函数doSomething<U>()
。不使用template关键字会报错
// MyClass.h
#include <memory>
template<typename T>
class MyClass {
public:
MyClass();
template<typename U>
void doSomething();
private:
class Impl;
std::unique_ptr<Impl> p_impl;
};
// MyClass.cpp
template<typename T>
class MyClass<T>::Impl {
public:
template<typename U>
void doSomething() {
// 实现具体逻辑
std::cout << "Doing something with type " << typeid(U).name() << "..." << std::endl;
}
};
template<typename T>
MyClass<T>::MyClass() : p_impl(std::make_unique<Impl>()) {}
template<typename T>
template<typename U>
void MyClass<T>::doSomething() {
p_impl->template doSomething<U>();
}
热门相关:仙城纪 朕是红颜祸水 最强反套路系统 法医娇宠,扑倒傲娇王爷 战神