以下示例详细说明了如何将std::shared_ptr作为泛型函数Put(const T& data)的参数来使用,涵盖了常见的语法场景。
#include <iostream>
#include <memory> // 智能指针头文件
#include <string>
#include <type_traits> // 用于类型特征检查
// 辅助模板:检查类型是否是 shared_ptr
template <typename T>
struct is_shared_ptr : std::false_type {};
template <typename T>
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
template <typename T>
constexpr bool is_shared_ptr_v = is_shared_ptr<T>::value;
// 模拟 Add 函数(Put 内部调用)
template <typename T>
bool Add(const T& data) {
// 打印数据(区分普通类型和智能指针)
if constexpr (is_shared_ptr_v<T>) {
if (data) { // 检查智能指针是否为空
std::cout << "Add shared_ptr: " << *data << std::endl;
} else {
std::cout << "Add shared_ptr: null" << std::endl;
}
} else {
std::cout << "Add normal data: " << data << std::endl;
}
return true; // 模拟成功返回
}
// 泛型 Put 函数(核心函数)
template <typename T>
bool Put(const T& data) {
return Add(data);
}
int main() {
// ========== 场景1:shared_ptr 作为泛型参数传入 Put ==========
// 1.1 创建非空 shared_ptr
std::shared_ptr<std::string> sp_str = std::make_shared<std::string>("Hello Shared_ptr");
// 直接传入(T 推导为 std::shared_ptr<std::string>)
Put(sp_str);
// 1.2 创建空 shared_ptr
std::shared_ptr<std::string> sp_null;
Put(sp_null); // 传入空智能指针
// ========== 场景2:const 修饰的 shared_ptr 传入(兼容 const 引用) ==========
const std::shared_ptr<int> sp_int = std::make_shared<int>(100);
Put(sp_int); // T 推导为 std::shared_ptr<int>
// ========== 场景3:临时 shared_ptr 传入(const 引用支持临时对象) ==========
Put(std::make_shared<double>(3.14159)); // 临时 shared_ptr 直接传入
// ========== 对比:普通类型传入(验证泛型兼容性) ==========
Put(std::string("Normal string"));
Put(123);
return 0;
}
语法说明
1. 泛型推导规则
当调用 Put(sp_str) 时:
sp_str 的类型是 std::shared_ptr<std::string>
- 模板参数
T 会自动推导为 std::shared_ptr<std::string>
Put 的形参 const T& data 等价于 const std::shared_ptr<std::string>& data(const 引用避免拷贝,且兼容临时对象)
2. shared_ptr 作为参数的核心要点
- const 引用传递:
const T& 是最优方式。它既避免了智能指针的拷贝(减少引用计数操作),又能接收左值(如 sp_str)和右值(如 std::make_shared 创建的临时对象)。这在设计涉及资源管理的网络/系统接口时尤为重要。
- 空指针检查:使用
shared_ptr 时,需要先检查其是否为空(if (data)),以避免解引用空指针导致程序崩溃。
- 类型推导兼容:无论
shared_ptr 本身是否被 const 修饰(如 const std::shared_ptr<int>),const T& 都能正确兼容。
3. 编译运行结果
Add shared_ptr: Hello Shared_ptr
Add shared_ptr: null
Add normal data: 100
Add normal data: 3.14159
Add normal data: Normal string
Add normal data: 123
总结
- 从语法角度看,将
std::shared_ptr 作为泛型函数 Put(const T& data) 的参数时无需特殊处理,直接传入即可,模板会自动将 T 推导为 std::shared_ptr<具体类型>。
- 推荐始终使用
const T& 作为形参类型,以避免不必要的智能指针拷贝,同时完美兼容各类使用场景。
- 在实际使用时,务必注意检查
shared_ptr 是否为空,这是避免空指针解引用错误的关键步骤。
|