2016-01-14 54 views
2

使用下一个定义与类模板

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; 
} 

这是为什么?

+0

'std :: vector '和'std :: vector '是完全不同的类型,但'B'是从'A'驱动的。 – Rabbid76

+0

有没有解决方法? – Pilpel

回答

2

std::vector<B*>std::vector<A*>是完全不同的类型,但BA派生。将数据复制从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

std::vector<B*>std::vector<A*>是不同的,在所有的,因为他们的模板参数型是不同的。

作为一种变通方法,可以使用的另一种vector构造函数,即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

0

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

您还应该使v成为f原型的参考。

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