我正在关注本教程以了解如何在 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); // getting error here
}
};
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&&'
要修复第 32 行中的这个错误,我必须准确返回指向派生类的返回指针,如下所示:
// return new static_cast<Derived*>(*this); to replace with
return new Derived(static_cast<const Derived&>(*this));
有人可以建议解决这个问题的正确方法吗?
您可以添加隐式转换:
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:
// added
operator const Derived &() const {
return static_cast<const Derived &>(*this);
}
virtual clone_inherit *clone_impl() const override {
return new Derived(*this); // getting error here
}
};