You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断传递给C++模板的参数是否为shared_ptr?

如何判断传递给C++模板的参数是否为shared_ptr?

这个问题其实很好解决,我们可以借助C的**类型特性(type traits)**来判断一个类型是不是std::shared_ptr。下面给你两种实用的实现方式,分别适配不同的C版本:

方式一:C++20及以上版本(推荐)

从C++20开始,标准库新增了std::is_specialization_of,可以直接用来判断一个类型是否是某个模板的特化版本。我们可以用它快速识别std::shared_ptr,直接把这个判断加到你的模板函数里就行:

#include <memory>
#include <type_traits>
#include <iostream>
#include <vector>

template <class T>
size_t get_size(T const &vec)
{
    if constexpr (std::is_pointer_v<T>)
    {
        std::cout << "pointer" << std::endl;
        return vec->size();
    }
    // 新增shared_ptr判断分支
    else if constexpr (std::is_specialization_of_v<T, std::shared_ptr>)
    {
        std::cout << "shared_ptr" << std::endl;
        return vec->size();
    }
    else
    {
        std::cout << "not pointer or shared_ptr" << std::endl;
        return vec.size();
    }
}

// 测试示例
int main() {
    std::vector<int> v{1,2,3};
    get_size(v); // 输出:not pointer or shared_ptr

    auto raw_ptr = &v;
    get_size(raw_ptr); // 输出:pointer

    auto sp = std::make_shared<std::vector<int>>({1,2,3});
    get_size(sp); // 输出:shared_ptr
    return 0;
}

方式二:兼容C11/C17版本

如果你的项目还在使用C++20之前的标准,我们可以手动实现一个类型特性来识别std::shared_ptr:

#include <memory>
#include <type_traits>
#include <iostream>
#include <vector>

// 基础模板:默认不是shared_ptr
template <typename T>
struct is_shared_ptr : std::false_type {};

// 特化模板:匹配任意类型参数的std::shared_ptr
template <typename U>
struct is_shared_ptr<std::shared_ptr<U>> : std::true_type {};

// 方便使用的变量模板,简化调用
template <typename T>
constexpr bool is_shared_ptr_v = is_shared_ptr<T>::value;

template <class T>
size_t get_size(T const &vec)
{
    if constexpr (std::is_pointer_v<T>)
    {
        std::cout << "pointer" << std::endl;
        return vec->size();
    }
    // 使用我们自己实现的类型特性判断
    else if constexpr (is_shared_ptr_v<T>)
    {
        std::cout << "shared_ptr" << std::endl;
        return vec->size();
    }
    else
    {
        std::cout << "not pointer or shared_ptr" << std::endl;
        return vec.size();
    }
}

// 测试示例
int main() {
    std::vector<int> v{1,2,3};
    get_size(v);

    auto raw_ptr = &v;
    get_size(raw_ptr);

    auto sp = std::make_shared<std::vector<int>>({1,2,3});
    get_size(sp);
    return 0;
}

补充说明

  • std::shared_ptr本身并不是原生指针类型,所以std::is_pointer_v<T>对它会返回false,不会和你之前的指针判断分支冲突,必须单独加一个分支处理。
  • 手动实现类型特性的核心是模板特化:我们针对std::shared_ptr<U>这个模板特化了is_shared_ptr结构体,让它继承std::true_type,这样就能识别任何类型参数的std::shared_ptr。

备注:内容来源于stack exchange,提问作者newandlost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 15:27:27