假设我有两组,一组包含vector<int>
,另一组包含vector<double>
实例。我只需要记住所有这些实例中的一个,即可根据某些条件进行进一步处理。从概念上讲,这个想法很简单:
vectorOfInterest *v;
for (i : set<vector<double>>)
if criteria_met(i)
{
*v = &i,
break;
}
for (i : set<vector<int>>)
if criteria_met(i)
{
*v = &i,
break;
}
// Do something with *v later.
请注意,此处的 set 在概念上是使用的,并不从字面上指代std::set
。我只能在末尾使用* v进行进一步处理,而不能在发现后立即使用* v,因为处理逻辑取决于上一次循环后发生的其他各个步骤,因此无法预先评估。
当前,我的方法是使用void指针,然后将其转换为适当的类型,具体取决于在以下位置找到感兴趣的向量的两个集合中的哪一个:
void* vectorOfInterest;
if (vectorOfInterest found within set<vector<double>>)
{
auto v = static_cast<std::vector<double>*>(vectorOfInterest);
// do something with v
}
else if (vectorOfInterest found within set<vector<int>>)
{
auto v = static_cast<std::vector<int>*>(vectorOfInterest);
// do something with v
}
这很好用,但是我想知道C ++中是否有更好的方法可以实现这一目标,也许不使用空指针和强制转换?例如,与此类似的东西:
std::vector<double>* vectorOfInterest;
for (i : set<vector<double>>)
if criteria_met(i)
{
vectorOfInterest = &i;
break;
}
for (i : set<vector<int>>)
if criteria_met(i)
{
vectorOfInterest = &i; // Obviously this won't compile.
break;
}
// Do something with vectorOfInterest directly, without needing a cast.
我假定,答案是没有直接的方法来获得这种行为,因为vector<double>*
与vector<int>*
根本不同,但是我想再次检查一下这个假设。我最初使用void指针的方法确实是这里的正确方法吗?
答案 0 :(得分:5)
不,没有。
例如,与Java泛型不同,std::vector<double>
与std::vector<int>
是完全不同的类型,因此,如果您尝试将指向一个的指针转换为另一种类型,则程序的行为由于违反严格别名而未定义。
除了从一开始就使用一致的类型外,您唯一可以做的就是将一个元素一个元素地复制到所需的类型中。
答案 1 :(得分:2)
编辑新版本的问题:variant<vector<int>*, vector<double>*>
对于您的用例可能有用。
没有将std::vector<double>*
转换为std::vector<int>*
的“正确”方法,因为这样的指针不能用于任何有用的东西。通过指针进行间接操作将具有不确定的行为。
也就是说,数据指针的reinterpret_cast
等于先转换为void*
,然后再转换static_cast
到另一种指针类型。但如前所述,在这里没有用。