gpt4 book ai didi

C++:将容器转换为不同但兼容类型的容器

转载 作者:可可西里 更新时间:2023-11-01 18:16:33 24 4
gpt4 key购买 nike

我经常碰巧有一个容器 C (或任何类型的包装类,甚至是智能指针)类型 T1 , 并且想要转换这样的 C<T1>进入C<T2> , 其中T2T1 兼容.

C++ 不允许我直接转换整个容器,并强制使用 reinterpet_cast会导致未定义的行为,所以我需要创建一个新的 C<T2>容器并用 C<T1> 重新填充它转换为 T2 的项目.此操作在时间和空间上都可能非常昂贵。

此外,在很多情况下,我很确定强制执行 reinterpret_cast可以很好地处理由任何存在的编译器编译的代码,例如当 T2 时是T1 const ,或者当 T1T2是指针。

是否有任何干净有效的方法来转换 C<T1>C<T2> ?
例如 container_cast创建并重新填充 C<T2> 的运算符(/函数?)当且仅当它不与 C<T1> 二进制兼容时?

最佳答案

除了其他人处理的所有其他问题:

  • 转换并不意味着相同的内存占用(想想转换操作......)
  • 模板类的潜在特化(在你的问题中是容器,但从编译器的角度来看,容器只是另一个模板)即使类型本身是二进制兼容的
  • 同一模板的不同实例化的不相关性(对于一般情况)

方法中存在一个根本不是技术性的基本问题。假设苹果是水果,则盛水果的容器既不是苹果的容器(简单演示),苹果的容器也不是水果的容器。尝试在一盒苹果中装下一个西瓜!

转到更多技术细节,并专门处理甚至不需要转换的继承,(派生对象已经是基类的对象),如果您被允许转换容器派生类型到基类型,那么您可以向容器添加无效元素:

class fruit {};
class apple : public fruit {};
class watermelon : public fruit {};
std::vector<apple*> apples = buy_box_of_apples();
std::vector<fruit*> & fruits = reinterpret_cast< std::vector<fruit*>& >(apples);
fruits.push_back( new watermelon() ); // ouch!!!

最后一行完全正确:您可以添加 watermelonvector<fruit*> .但实际效果是您添加了一个 watermelon。到 vector<apple*> ,这样做就破坏了类型系统。

并非所有乍一看都很简单的东西实际上都是理智的。这类似于无法转换 int ** 的原因。到 const int **即使第一个想法是应该允许它。事实上,允许这样做会破坏语言(在这种情况下是 const 正确性):

const int a = 5;
int *p = 0;
int **p1 = &p; // perfectly fine
const int **p2 = p1; // should this be allowed??
*p2 = &a; // correct, p2 points to a pointer to a const int
**p1 = 100; // a == 100!!!

这让我们回到您在另一个答案的评论之一中提供的示例(为了证明这一点,我将使用 vector 而不是集合,因为集合内容是不可变的):

std::vector<int*> v1;
std::vector<const int*> &v2 = v1; // should this be allowed?
const int a = 5;
v2.push_back( &a ); // fine, v2 is a vector of pointers to constant int
// rather not: it IS a vector of pointers to non-const ints!
*v1[0] = 10; // ouch!!! a==10

关于C++:将容器转换为不同但兼容类型的容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4605633/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com