peo*_*oro 7 c++ containers casting
它经常发生在我身上有AA容器C的类型(或任何类型的包装类,甚至是智能指针)T1,并希望这种转换C<T1>成C<T2>,其中T2是兼容的T1.
C++不允许我直接转换整个容器,并且强制a reinterpet_cast会导致未定义的行为,所以我需要创建一个新的C<T2>容器并使用生成的C<T1>项目重新填充它T2.这种操作在时间和空间上都非常昂贵.
而且许多情况下,我敢肯定,强制reinterpret_cast将正常工作与任何编译器编译的代码曾经存在,例如,当T2是T1 const时,或者T1和T2是指针.
是否有转换任何清洁和高效的方式C<T1>在C<T2>?
例如,一个container_cast运算符(/ function?)创建并重新填充C<T2>if和only,如果它不是二进制兼容的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!!!
Run Code Online (Sandbox Code Playgroud)
最后一行完全正确:您可以将 a 添加watermelon到 a vector<fruit*>。但最终的结果是您将 a 添加watermelon到 a 中vector<apple*>,这样做就破坏了类型系统。
并非所有乍一看很简单的东西实际上都是理智的。int **这与为什么你不能将 an 转换为 a的原因类似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!!!
Run Code Online (Sandbox Code Playgroud)
这让我们回到您在另一个答案的评论之一中提供的示例(为了证明这一点,我将使用向量而不是集合,因为集合内容是不可变的):
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
Run Code Online (Sandbox Code Playgroud)