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

C++返回智能指针与协变的代码错误修复咨询

C++智能指针协变克隆实现的编译错误修复

我在学习C++中返回智能指针及协变实现时遇到编译错误,原代码如下:

#include <memory>
#include <iostream>

class cloneable
{
public:
   virtual ~cloneable() {}

   std::unique_ptr<cloneable> clone() const
   {
      return std::unique_ptr<cloneable>(this->clone_impl());
   }

private:
   virtual cloneable * clone_impl() const = 0;
};

///////////////////////////////////////////////////////////////////////////////

template <typename Derived, typename Base>
class clone_inherit: public Base
{
public:
   std::unique_ptr<Derived> clone() const
   {
      return std::unique_ptr<Derived>(static_cast<Derived *>(this->clone_impl()));
   }

private:
   virtual clone_inherit * clone_impl() const override
   {
      return new Derived(*this); // 此处报错
   }
};


class concrete : public clone_inherit<concrete, cloneable>
{
  
};

int main()
{
  std::unique_ptr<concrete> c = std::make_unique<concrete>();
}

编译时出现如下错误:

/tmp/0RmVdQYjfA.cpp: In instantiation of 'clone_inherit<Derived, Base>* clone_inherit<Derived, Base>::clone_impl() const [with Derived = concrete; Base = cloneable]':
/tmp/0RmVdQYjfA.cpp:30:28:   required from here
/tmp/0RmVdQYjfA.cpp:32:14: error: no matching function for call to 'concrete::concrete(const clone_inherit<concrete, cloneable>&)'
   32 |       return new Derived(*this);
      |              ^~~~~~~~~~~~~~~~~~
/tmp/0RmVdQYjfA.cpp:37:7: note: candidate: 'constexpr concrete::concrete()'
   37 | class concrete : public clone_inherit<concrete, cloneable>
      |       ^~~~~~~~
/tmp/0RmVdQYjfA.cpp:37:7: note:   candidate expects 0 arguments, 1 provided
/tmp/0RmVdQYjfA.cpp:37:7: note: candidate: 'constexpr concrete::concrete(const concrete&)'
/tmp/0RmVdQYjfA.cpp:37:7: note:   no known conversion for argument 1 from 'const clone_inherit<concrete, cloneable>' to 'const concrete&'
/tmp/0RmVdQYjfA.cpp:37:7: note: candidate: 'constexpr concrete::concrete(concrete&&)'
/tmp/0RmVdQYjfA.cpp:37:7: note:   no known conversion for argument 1 from 'const clone_inherit<concrete, cloneable>' to 'concrete&&'

我尝试将报错行修改为:

// return  new static_cast<Derived*>(*this); 替换为
return new Derived(static_cast<const Derived&>(*this));

正确修复方法

编译错误的核心原因是:在clone_inherit<concrete, cloneable>的clone_impl函数中,*this的类型是const clone_inherit<concrete, cloneable>&,而concrete的拷贝构造函数仅接受const concrete&类型的参数。虽然concrete继承自clone_inherit<concrete, cloneable>,但编译器不会自动将基类引用隐式转换为派生类引用,必须显式指定转换。

你的尝试方向是正确的,只需确保转换的安全性即可。最终的clone_impl函数应修改为:

virtual clone_inherit * clone_impl() const override
{
    return new Derived(static_cast<const Derived&>(*this));
}

这种静态转换是安全的,因为clone_inherit<Derived, Base>是Derived的直接基类,当前的this指针必然指向Derived类型的对象(因为concrete继承自clone_inherit<concrete, cloneable>)。

另外,也可以选择使用dynamic_cast,但在这个场景下静态转换更高效,且逻辑上完全安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:38:17