c++使用派生类进行模板转换

发布于 2024-08-19 00:24:45 字数 601 浏览 9 评论 0 原文

#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 上它无法编译:错误:形式参数 x 类型为 const std::pair & 调用 std::vector >::push_back(const std::pair & ) 正在传递 std::pair

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

I don't understand why this compiles (maybe somebody can kindly provide detailed explanation? Is it something related to name look-up?

Btw, on Solaris, SunStudio12 it doesn't compile: 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*>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ぺ禁宫浮华殁 2024-08-26 00:24:45

std::pair 有一个构造函数模板:

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

“效果:从参数的相应成员初始化成员,根据需要执行隐式转换。” (C++03、20.2.2/4)

从派生类指针到基类指针的转换是隐式的。

std::pair has a constructor template:

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

"Effects: Initializes members from the corresponding members of the argument, performing implicit conversions as needed." (C++03, 20.2.2/4)

Conversion from a derived class pointer to a base class pointer is implicit.

伪心 2024-08-26 00:24:45

因为 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)

Because B is derived from A, the vector v will contain pointers to base class structures of the object b. therefore, you could access the members of A, i.e.

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

EDIT:
My mistake, as pointed out below, you can still cast to pointers of type B since the vector is of pointers, not objects, so no object slicing has occurred.

A call such as

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

will not compile since the elements in the vector are base class pointers and cannot point to derived class members without a cast, i.e.

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

Also note that a dynamic cast, as in

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

will not compile with the following error in 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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文