【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>();
}

浙公網安備 33010602011771號