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

C++继承std::shared_ptr的构造函数跨编译器行为差异问题

问题根本原因

这是编译器对C++标准的实现差异导致的问题,其中MSVC的行为属于非标准扩展,GCC/Clang的编译结果符合标准要求。

核心规则说明

  1. 初始化方式差异
    你代码中出错的行是复制初始化场景:
    MyPtr<int> a = std::make_shared<int>();
    
    复制初始化要求源类型std::shared_ptr<int>到目标类型MyPtr<int>存在合法的隐式转换,而直接初始化MyPtr<int> a(std::make_shared<int>())不存在隐式转换要求,因此在所有编译器下都可以正常编译。
  2. 继承构造函数的限制
    你通过using base::base;确实继承了std::shared_ptr的所有构造函数,包括它的拷贝、移动构造函数。但C++标准明确规定:基类自身的拷贝、移动构造函数被继承到派生类后,不会被视为派生类的转换构造函数,不能用于隐式类型转换场景。
    你传入的std::shared_ptr<int>右值刚好匹配基类的移动构造函数签名,因此GCC/Clang认为没有合法的隐式转换路径,抛出转换错误。
  3. MSVC的非标准行为
    MSVC没有实现上述标准限制,允许继承来的基类拷贝/移动构造函数作为派生类的转换构造函数使用,属于编译器的非标准扩展,因此可以编译通过你的代码。

修复方案

如果需要代码跨编译器兼容,只需要手动添加对应的转换构造函数即可:

#include <memory>
template <typename T>
class MyPtr : public std::shared_ptr<T> {
    using base = std::shared_ptr<T>;
public:
    using base::operator=;
    using base::base;
    // 手动添加隐式转换需要的构造函数
    MyPtr(base&& other) noexcept : base(std::move(other)) {}
    MyPtr(const base& other) : base(other) {}
};
int main() {
    MyPtr<int> a = std::make_shared<int>(); // 所有编译器下均编译通过
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:39:01