C++ 协变模板

2021-12-13 00:00:00 templates c++ covariance

我觉得以前有人问过这个问题,但我无法在 SO 上找到它,也无法在 Google 上找到任何有用的信息.也许协变"不是我要找的词,但这个概念与函数的协变返回类型非常相似,所以我认为它可能是正确的.这是我想要做的,它给了我一个编译器错误:

I feel like this one has been asked before, but I'm unable to find it on SO, nor can I find anything useful on Google. Maybe "covariant" isn't the word I'm looking for, but this concept is very similar to covariant return types on functions, so I think it's probably correct. Here's what I want to do and it gives me a compiler error:

class Base;
class Derived : public Base;

SmartPtr<Derived> d = new Derived;
SmartPtr<Base> b = d; // compiler error

假设这些类已经完全充实了……我想你明白了.由于某些不清楚的原因,它无法将 SmartPtr 转换为 SmartPtr.我记得这在 C++ 和许多其他语言中很正常,但目前我不记得为什么.

Assume those classes are fully fleshed out... I think you get the idea. It can't convert a SmartPtr<Derived> into a SmartPtr<Base> for some unclear reason. I recall that this is normal in C++ and many other languages, though at the moment I can't remember why.

我的根本问题是:执行此赋值操作的最佳方法是什么?目前,我正在将指针从 SmartPtr 中拉出,明确地将其向上转换为基本类型,然后将其包装在适当类型的新 SmartPtr 中(请注意,这不会泄漏资源,因为我们自己开发的 SmartPtr 类使用了侵入式引用计数).这又长又乱,尤其是当我需要将 SmartPtr 包装在另一个对象中时……有什么快捷方式吗?

My root question is: what is the best way to perform this assignment operation? Currently, I'm pulling the pointer out of the SmartPtr, explicitly upcasting it to the base type, then wrapping it in a new SmartPtr of the appropriate type (note that this is not leaking resources because our home-grown SmartPtr class uses intrusive reference counting). That's long and messy, especially when I then need to wrap the SmartPtr in yet another object... any shortcuts?

推荐答案

复制构造函数和赋值运算符都应该能够采用不同类型的 SmartPtr 并尝试将指针从一个复制到另一个.如果类型不兼容,编译器会抱怨,如果它们兼容,你就解决了你的问题.像这样:

Both the copy constructor and the assignment operator should be able to take a SmartPtr of a different type and attempt to copy the pointer from one to the other. If the types aren't compatible, the compiler will complain, and if they are compatible, you've solved your problem. Something like this:

template<class Type> class SmartPtr
{
    ....
    template<class OtherType> SmartPtr(const SmartPtr<OtherType> &blah) // same logic as the SmartPtr<Type> copy constructor

    template<class OtherType> SmartPtr<Type> &operator=(const SmartPtr<OtherType> &blah) // same logic as the SmartPtr<Type> assignment operator
};

相关文章