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

これがコンパイルされる理由がわかりません(誰かが親切に詳細な説明を提供できるかもしれませんか?名前の検索に関連するものですか?

ところで、Solaris では、SunStudio12 はコンパイルされません。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*>

4

2 に答える 2

13

std::pairコンストラクター テンプレートがあります。

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

「効果: 引数の対応するメンバーからメンバーを初期化し、必要に応じて暗黙的な変換を実行します。」(C++03、20.2.2/4)

派生クラス ポインターから基底クラス ポインターへの変換は暗黙的です。

于 2010-01-26T04:04:13.617 に答える
0

B は A から派生しているため、ベクトル v にはオブジェクト b の基本クラス構造へのポインターが含まれます。したがって、A のメンバーにアクセスできます。

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

編集:私の間違いは、以下に指摘されているように、ベクトルはオブジェクトではなくポインターであるため、タイプ B のポインターにキャストできるため、オブジェクトのスライスは発生しません。

のような呼び出し

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

ベクトル内の要素は基本クラス ポインターであり、キャストなしでは派生クラス メンバーを指すことができないため、コンパイルされません。つまり、

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

次のような動的キャストにも注意してください。

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

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)
于 2010-01-26T04:08:52.500 に答える