获取模板以匹配常量 T* 和非常量 T* 的不同序列

Getting template to match different sequences of const T* and non-const T*

本文关键字:常量 非常 获取      更新时间:2023-10-16

这是一些重构代码的模板。drPindrPort都是drNode的子类。此代码从原始包含的指针中剥离const限定,并基于它构建两个新的数据结构(新的数据结构需要指向映射中的非常量的指针,因为使用它们的代码并未全部正确限制)。现在,第一个参数要么是const std::vector<const drPin*>,要么是const std::vector<drPort*>。为了使第二个匹配,我目前正在将其复制到const drPort*向量,然后再调用:std::vector<const drPort*> constPorts(aPorts.cbegin(), aPorts.cend());

template <typename T>
static void buildFlatNetNodes(const std::vector<const T*>& aPins,
std::map<drNet*, std::list<drNode*>> &flatNetNodes,
std::vector<drNet *> &netOrder)
{
for (const T* constPin : aPins)
{
T *curPin = const_cast<T *>(constPin);
drNet* curFlatNet = curPin->getNet();
auto ii = flatNetNodes.find(curFlatNet);
if (ii == flatNetNodes.end())
{
flatNetNodes[curFlatNet] = std::list<drNode *>{curPin};
netOrder.push_back(curFlatNet);
}
else
ii->second.push_back(curPin);
}
}

现在我想在std::list<drNode*>上使用相同的模板。 我可以做同样的复制技巧来获得std::vector<const drNode*>,但是这个列表将比端口向量长得多,因此额外的复制开销会相应更大,我想避免它。尝试使容器类型通用(通过添加另一层模板并将第一个类型声明为const S<const T*>)在使用std::list<const drNode*>调用时无法编译。 使用开始/结束迭代器而不是通过引用传递容器可能会起作用 - 还有其他建议吗? 有没有办法将foo*容器传递给期望const foo*容器的代码? (我似乎记得有一个原因不起作用,但我目前似乎没有正确的搜索词组合来找到它)。

你可以这样做:

template <typename T>
T* cast_as_non_const(const T* p)
{
return const_cast<T*>(p);
}
template <typename T>
static void buildFlatNetNodes(const std::vector<T>& aPins,
std::map<drNet*, std::list<drNode*>>& flatNetNodes,
std::vector<drNet*>& netOrder)
{
for (const auto* constPin : aPins)
{
auto* curPin = cast_as_non_const(constPin);
drNet* curFlatNet = curPin->getNet();
auto ii = flatNetNodes.find(curFlatNet);
if (ii == flatNetNodes.end())
{
flatNetNodes[curFlatNet] = {curPin};
netOrder.push_back(curFlatNet);
}
else
ii->second.push_back(curPin);
}
}
// std::vector<const drPin*> pins;
// std::vector<drPort*> ports;
// std::map<drNet*, std::list<drNode*>> flatNetNodes;
// std::vector<drNet*> netOrder;
//
// buildFlatNetNodes(pins, flatNetNodes, netOrder);
// buildFlatNetNodes(ports, flatNetNodes, netOrder);