Pergunta

#include <vector>

struct A {int a;};
struct B : public A {char b;};

int main()
{
  B b;
  typedef std::pair<A*, A*> MyPair;
  std::vector<MyPair> v;
  v.push_back(std::make_pair(&b, &b)); //compiler error should be here(pair<B*,B*>)
  return 0;
}

Não entendo por que isso compila (talvez alguém possa fornecer explicações detalhadas? É algo relacionado ao nome da pesquisa?

BTW, em Solaris, Sunstudio12, ele não compila: error : formal argument x of type const std::pair<A*, A*> & in call to std::vector<std::pair<A*,A*> >::push_back(const std::pair<A*, A*> & ) is being passed std::pair<B*, B*>

Foi útil?

Solução

std::pair tem um modelo de construtor:

template<class U, class V> pair(const pair<U, V> &p);

"Efeitos: inicializa os membros dos membros correspondentes do argumento, realizando conversões implícitas conforme necessário". (C ++ 03, 20.2.2/4)

A conversão de um ponteiro de classe derivada em um ponteiro de classe base está implícito.

Outras dicas

Como B é derivado de A, o vetor V conterá ponteiros para as estruturas de classe base do objeto b. Portanto, você pode acessar os membros de A, ou seja,

std::cout << v[0].first->a;

EDIT: Meu erro, como apontado abaixo, você ainda pode ser lançado para ponteiros do tipo B, já que o vetor é de ponteiros, não objetos, portanto, nenhum fatiamento de objetos ocorreu.

Uma chamada como

std::cout << v[0].first->b; 

não vai compilar, pois os elementos do vetor são ponteiros de classe base e não podem apontar para membros de classe derivados sem elenco, ou seja,

 std::cout << static_cast<B*>(v[0].first)->b; 

Observe também que um elenco dinâmico, como em

std::cout << dynamic_cast<B*>(v[0].first)->b;  

não vai compilar com o seguinte erro no GCC:

cast.cpp:14: error: cannot dynamic_cast ‘v.std::vector<_Tp, _Alloc>::operator[] [with _Tp = std::pair<A*, A*>, _Alloc = std::allocator<std::pair<A*, A*> >](0u)->std::pair<A*, A*>::first’ (of type struct A*’) to type struct B*’ (source type is not polymorphic)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top