派生クラスを備えたC ++テンプレートキャスト
-
22-09-2019 - |
質問
#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;
}
なぜこれがコンパイルされるのかわかりません(誰かが親切に詳細な説明を提供できるかもしれませんか?それは名前のルックアップに関連するものですか?
ところで、ソラリス、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*>
解決
std::pair
コンストラクターテンプレートがあります:
template<class U, class V> pair(const pair<U, V> &p);
「効果:対応する議員のメンバーを初期化し、必要に応じて暗黙の変換を実行します。」 (C ++ 03、20.2.2/4)
派生クラスポインターからベースクラスポインターへの変換は暗黙的です。
他のヒント
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)
所属していません StackOverflow