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

C++20风格下std::vector<shared_ptr<Base>>转vector<shared_ptr<Derived>>方法

C++20风格实现std::vector<std::shared_ptr<Base>>到std::vector<std::shared_ptr<Derived>>的转换

前提类定义

class Base
{
};

class Derived : public Base
{
};

现有存储基类智能指针的容器:

std::vector<std::shared_ptr<Base>> baseVec;

需要转换为存储派生类智能指针的容器:

std::vector<std::shared_ptr<Derived>> derivedVec;

两种转换方案(C++20风格)

方案1:无类型检查(确保所有元素都是Derived实例)

如果能100%确定baseVec中的每个shared_ptr<Base>都指向Derived对象,可以用static_pointer_cast配合C++20范围特性快速转换:

写法1:构造函数直接传入转换逻辑

#include <vector>
#include <memory>

std::vector<std::shared_ptr<Derived>> derivedVec(
    baseVec.begin(), baseVec.end(),
    [](const std::shared_ptr<Base>& ptr) {
        return std::static_pointer_cast<Derived>(ptr);
    }
);

写法2:用std::views::transform生成视图再构造

#include <vector>
#include <memory>
#include <ranges>

auto derived_view = baseVec | std::views::transform(
    [](auto&& ptr) {
        return std::static_pointer_cast<Derived>(std::forward<decltype(ptr)>(ptr));
    }
);

std::vector<std::shared_ptr<Derived>> derivedVec(derived_view.begin(), derived_view.end());

注意:此方式无类型校验,若存在非Derived的子类实例,会触发未定义行为,仅在场景明确时使用。


方案2:类型安全转换(过滤无效元素)

如果baseVec中可能混有其他Base子类实例,必须用dynamic_pointer_cast做类型检查,并过滤转换失败的空指针:

标准写法

#include <vector>
#include <memory>
#include <ranges>

auto filtered_view = baseVec 
    | std::views::transform(
        [](auto&& ptr) {
            return std::dynamic_pointer_cast<Derived>(std::forward<decltype(ptr)>(ptr));
        }
    )
    | std::views::filter(
        [](const auto& ptr) { return ptr != nullptr; }
    );

std::vector<std::shared_ptr<Derived>> derivedVec(filtered_view.begin(), filtered_view.end());

简化写法(利用std::identity)

C++20的std::identity可以直接过滤空指针(需包含<functional>):

#include <vector>
#include <memory>
#include <ranges>
#include <functional>

std::vector<std::shared_ptr<Derived>> derivedVec(
    baseVec 
    | std::views::transform(
        [](auto&& ptr) {
            return std::dynamic_pointer_cast<Derived>(std::forward<decltype(ptr)>(ptr));
        }
    )
    | std::views::filter(std::identity{})
);

此方案会自动跳过无法转换为Derived的元素,最终derivedVec仅包含有效的Derived智能指针。


内容的提问来源于stack exchange,提问作者Jan Hackenberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:37:03