【问题标题】:Getting template to match different sequences of const T* and non-const T*获取模板以匹配 const T* 和非常量 T* 的不同序列
【发布时间】:2019-11-15 05:12:07
【问题描述】:

这是来自一些重构代码的模板。 drPindrPort 都是 drNode 的子类。此代码从原始包含的指针中去除 const 限定,并基于它构建两个新数据结构(新数据结构需要指向映射中的非常量的指针,因为使用它们的代码并非都是正确的 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&lt;drNode*&gt; 上使用相同的模板。我可以使用相同的复制技巧来获得std::vector&lt;const drNode*&gt;,但是这个列表将比端口向量长得多,因此额外的复制开销会相应更大,我想避免它。尝试使容器类型通用(通过添加另一层模板并将第一个类型声明为const S&lt;const T*&gt;)在使用std::list&lt;const drNode*&gt; 调用时编译失败。使用开始/结束迭代器而不是通过引用传递容器可能会起作用 - 还有其他建议吗?有没有办法将foo* 的容器传递给期望const foo* 的容器的代码? (我似乎记得有一个不起作用的原因,但我目前似乎没有正确的搜索词组合来找到它)。

【问题讨论】:

    标签: c++ pointers vector c++14 constants


    【解决方案1】:

    你可以这样做:

    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);
    

    【讨论】:

    • 宾果游戏。如果我将 aPins 的声明更改为 const T& aPins,它也适用于 std::list 版本。这就是我需要的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    相关资源
    最近更新 更多