使用类模板进行隐式转换

时间:2016-01-14 05:25:32

标签: c++

使用下一个定义

class A {};
class B : public A {};

void f(A* a) {}

可以调用f(new B),因为B*已隐式转换为A*,对吗?

但是,对类std::vector等类模板执行相同操作时,会产生编译错误。

void f(std::vector<A*> v)
{}

int main()
{
    std::vector<B*> v;
    f(v); //error! "no suitable user-defined conversion..."

    return 0;
}

为什么?

3 个答案:

答案 0 :(得分:2)

std::vector<B*>std::vector<A*>是完全不同的类型,但B来自A。要将数据从std::vector<B*>复制到std::vector<A*>,请使用std::copystd::back_inserter

#include <algorithm> // std::copy
#include <iterator>  // std::back_inserter

std::vector<B*> b;
std::vector<A*> a;
std::copy( b.begin(), b.end(), std::back_inserter( a ) );

...或使用统一初始化初始化a

std::vector<B*> b;
std::vector<A*> a{ b.begin(), b.end() };

答案 1 :(得分:1)

std::vector<B*>std::vector<A*>完全不同,因为它们的模板参数的类型不同。

作为解决方法,您可以使用vector的另一个ctor,即template<class InputIt> std::vector::vector(InputIt first, InputIt last),例如:

f(std::vector<A*>(v.begin(), v.end()));

或者只是(需要c ++ 11)

f({v.begin(), v.end()});

LIVE

答案 2 :(得分:0)

正如评论中所指出的,std::vector<A*>std::vector<B*>的类型不同。这并不妨碍您在B*向量中存储std::vector<A*>个对象。正如您所推测的,基类指针可以指向派生对象,这就是您可以将它们存储在基类向量中的原因。

您还应该在v的原型中f作为参考。

Punchline:你真的不需要std::vector<B*>