使容器协变
Make container covariant
我正在实现指针my_ptr_vector
的自定义向量。
我有一个类Base
和一个Derived
派生Base
。
我有一个方法应该在my_ptr_vector<Base>
和my_ptr_vector<Derived>
上起作用(通过const引用!)。当然,它只调用来自Base
类的元素方法。
但是,编译器抱怨它没有办法将my_ptr_vector<Derived>
转换成my_ptr_vector<Base>
。
重现问题的最小示例:
#include <vector>
#include <memory>
class Base {};
class Derived : public Base {};
template<typename Element>
class my_ptr_vector : public std::vector< std::unique_ptr< Element > > {};
void funct(const my_ptr_vector<Base>& vect) {}
int main()
{
my_ptr_vector<Derived> vect;
funct(vect);
}
错误:no suitable user-defined conversion from "my_ptr_vector<Derived>" to "const my_ptr_vector<Base>" exists
我在这里发现,如果我从my_ptr_vector<U>
提供构造函数和赋值操作符,使用U
泛型,这样U*
可以转换为T*
,我可以使它工作。
实际上,如果在这个例子中我将类更改为this,它就可以工作了
template<typename Element>
class my_ptr_vector : public std::vector< std::shared_ptr< Element > > {
public:
my_ptr_vector() {}
///copy constructor from vector of pointers to generic U
template<typename DerivedElement>
my_ptr_vector(const my_ptr_vector<DerivedElement>& oth)
{
printf("Oh, noes!"); //we don't want this method executed!
resize(oth.size());
for (std::shared_ptr< Element > ptr : oth)
{
push_back(ptr);
}
}
};
然而,它确实在构造函数中执行print
语句——这不仅仅是暗示它不应该担心;它实际上是在执行转换!
有办法避免这种情况吗?
另一个可能的解决方案当然是使func
模板化:
template<typename T>
void funct(const my_ptr_vector<T>& vect) {}
但是,这样我就丢失了在func
内部,vect
的元素总是Base
类型的信息。
这似乎是您想要的。代码的第二部分,复制函数,不需要修改。
我不认为你可以摆脱需要转换到std::unique_ptr
。它想要这样,即使它推送的是Base*
。
#include <vector>
#include <memory>
class Base {};
class Derived : public Base {};
template<typename Element>
class my_ptr_vector : public std::vector< std::unique_ptr< Element > > {};
void funct(const my_ptr_vector<Base>& vect) {}
int main()
{
my_ptr_vector<Base> vect;
vect.push_back(std::unique_ptr<Base>(new Derived));
funct(vect);
}
相关文章:
- 没有找到相关文章