【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

template
class MyClass {
public:
void doSomething();

private:
class Impl;
static std::unique_ptr p_impl; // 静态 p_impl 变量的声明
};

// MyClass.cpp

template
class MyClass::Impl {
public:
void doSomething() {
// 实现具体逻辑
std::cout << "Doing something..." << std::endl;
}
};

template
std::unique_ptr<typename MyClass::Impl> MyClass::p_impl = std::make_unique<typename MyClass::Impl>(); // 静态 p_impl 变量的定义

template
void MyClass::doSomething() {
p_impl->doSomething();
}

如果一个模板类使用p_impl技术,同时内部包含模板函数,那么模板函数的调用需要额外使用template关键字

在最后的代码p_impl->template doSomething<U>();处,使用template关键字告诉编译器我们正在引用一个模板成员函数doSomething<U>()。不使用template关键字会报错

// MyClass.h

include

template
class MyClass {
public:
MyClass();
template
void doSomething();

private:
class Impl;
std::unique_ptr p_impl;
};

// MyClass.cpp

template
class MyClass::Impl {
public:
template
void doSomething() {
// 实现具体逻辑
std::cout << "Doing something with type " << typeid(U).name() << "..." << std::endl;
}
};

template
MyClass::MyClass() : p_impl(std::make_unique()) {}

template
template
void MyClass::doSomething() {
p_impl->template doSomething();
}

posted @ 2023-05-15 01:08  缙云烧饼  阅读(376)  评论(0)    收藏  举报