【问题标题】:Can iter_swap be specialised?iter_swap 可以特化吗?
【发布时间】:2012-08-26 23:42:05
【问题描述】:

如果我有一个容器 std::vector<T*> items,我可以创建一个 IndirectIterator 包装 std::vector<T*>::iterator 并允许迭代 T 而不是 T*

我可以将iter_swap 专门用于IndirectIterator 以使标准算法(例如std::sort)通过指针交换项目吗?

即,如果我写以下内容,它会对标准算法产生任何影响吗?

namespace some_namespace
{
    template <typename IterT>
    class IndirectIterator
    {
            IterT m_base;
        public:
            typedef IterT base_iterator;
            typedef /* ... */ reference;

            /* ... */

            reference operator*() const { **m_base; }

            const base_iterator& base() const { return m_base; }
            base_iterator& base() { return m_base; }
    };

    template <typename T>
    void iter_swap(IndirectIterator<T>& a, IndirectIterator<T>& b)
    {
        using std::iter_swap;
        iter_swap(a.base(), b.base());
    }
}

这种专门化的好处是它交换指针而不是完整的 T 实例,因此它更快(可能)。

【问题讨论】:

    标签: c++ algorithm vector c++11 containers


    【解决方案1】:

    据我所知,iter_swap 仅在std::reverse 中使用,并且没有提及任何类型的参数相关查找:它始终使用std::iter_swap。而且由于不允许您在 std 命名空间中重载函数,因此您很不走运。

    【讨论】:

    • 检查来自 libc++ 的一些标头这看起来是正确的,尽管它有点令人失望。我想我可以使用自定义引用类来做到这一点,但我不确定是否值得让交换更好。
    • 在 C++11 中(至少),std::sort 使用 std::iter_swap。 (而且我必须专门/定义 std::iter_swap 以使某个特殊的迭代器与 std::sort 一起工作。
    • 您仍然可以在 std 命名空间中专门化模板,只要它们专门用于用户定义的参数。
    • 另外,一个实现只在一个地方使用std::iter_swap这一事实并不意味着它是唯一使用它的地方,也不意味着这种使用是完全正确的......
    • @AnT 只要你保持与非专业版本相同的语义。
    【解决方案2】:

    我可以专门 iter_swapIndirectIterator 制定标准吗 算法(如std::sort)通过指针交换项目?

    你总是可以让你的超载/专业化。但是,您的问题是您是否可以在 iter_swap inside 命名空间 std 中专门化。

    我认为标准中的答案尚不清楚。 我发现在某些情况下,我必须在std 中定义一个特殊的iter_swap,以便std::sort 使用它。在 gcc 标准库中 std::sort 使用合格的 std::iter_swap

    这可能是std::sort 中的一个缺陷。 IMO std::sort 应该调用不合格的swap_iter

    即,如果我写以下内容,它会对标准产生任何影响 算法?

    不在 GCC 中(至少)因为标准算法使用合格的std::iter_swap(错误?) 我认为标准并不清楚。

    【讨论】:

      【解决方案3】:

      您可以重新打开 std 命名空间并专门化 std 内的模板,只要您将它们专门用于用户定义的类型。在您的情况下,您实际上可以将 std::iter_swap 专门用于您的目的,只需确保您在 std 命名空间中执行此操作,而不是在您自己的命名空间中(如您的示例中所示)。不是很优雅,但是是允许的。

      【讨论】:

        猜你喜欢
        • 2021-10-17
        • 2011-06-01
        • 2022-08-08
        • 2019-01-31
        • 1970-01-01
        • 2013-03-05
        相关资源
        最近更新 更多