使用decltype返回迭代器

Using decltype to return iterator

本文关键字:迭代器 返回 decltype 使用      更新时间:2023-10-16

我有这个类:

template <typename T>
class Hybrid
{
public:
    Hybrid() : m_activeStackSize(0) {}
private:
    std::list<T> data;
    size_t m_activeStackSize;
    auto internal_peek() -> decltype(data)::iterator
    {
        if (m_activeStackSize) // peek from stack
        {
            decltype(data)::iterator itr = data.end();
            std::advance(itr, -1);
            return itr;
        }
        else //peek from queue
        {
            decltype(data)::iterator itr = data.begin();
            return itr;
        }
    }
};

当试图在Microsoft Visual Studio 2015上编译时,我得到了:

main.cpp(12):错误C3646:"迭代器":未知重写说明符

我不明白为什么它不让我返回std::list<T>类型的iterator,而正文代码:

decltype(data)::iterator itr = data.end();

decltype(data)::iterator itr = data.begin();

编译成功。

如何显式使用decltype成功返回std::list iterator

删除-> decltype(data)::iterator编译成功。

编辑:用GCC编译并为每个decltype添加typename编译得很好,MSVC仍然会出错。

decltype(data)::iterator是一个依赖类型。因此,必须使用typename

auto internal_peek() -> typename decltype(data)::iterator
                       //  ^^^^^ here
{
    if (m_activeStackSize) // peek from stack
    {
        typename decltype(data)::iterator itr = data.end();
        // ^^^^^ and here
        std::advance(itr, -1);
        return itr;
    }
    else //peek from queue
    {
        typename decltype(data)::iterator itr = data.begin();
        // ^^^^^ and here
        return itr;
    }
}

MSVC可能的变通办法。

// Declare iterator as a type.
using iterator = typename std::list<T>::iterator;
iterator internal_peek()
{
    if (m_activeStackSize) // peek from stack
    {
        iterator itr = data.end();
        std::advance(itr, -1);
        return itr;
    }
    else //peek from queue
    {
        iterator itr = data.begin();
        return itr;
    }
}

在C++14中,您根本不需要decltype()。根据C++14,以下是正确的(据我所知,MSVC并不完全支持C++14):

   auto internal_peek()
    {
        if (m_activeStackSize) // peek from stack
        {
            auto itr = data.end();
            std::advance(itr, -1);
            return itr;
        }
        else //peek from queue
        {
            auto itr = data.begin();
            return itr;
        }
    }