Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何退回包装容器的反向适配器?_C++_C++11_Visual Studio 2012 - Fatal编程技术网

C++ 如何退回包装容器的反向适配器?

C++ 如何退回包装容器的反向适配器?,c++,c++11,visual-studio-2012,C++,C++11,Visual Studio 2012,我有一个类,它有一个deque,用作堆栈(可能是向量,只是碰巧选择了deque) 无论如何,我希望允许消费者迭代堆栈的内容(std::stack无法做到这一点)。我目前正在使用push_back()将项目推送到堆栈上,因此,如果按正向顺序迭代内容,则会从堆栈的底部到顶部 我更愿意以相反的顺序公开内容,以便使用for(auto e:thestack)在堆栈上迭代以自顶向下的方式工作 我发现这显示了两个解决方案,用于反转新for循环语法(以及基于范围的算法)的迭代顺序 我不清楚的是如何提供一个简单的

我有一个类,它有一个deque,用作堆栈(可能是向量,只是碰巧选择了deque)

无论如何,我希望允许消费者迭代堆栈的内容(std::stack无法做到这一点)。我目前正在使用push_back()将项目推送到堆栈上,因此,如果按正向顺序迭代内容,则会从堆栈的底部到顶部

我更愿意以相反的顺序公开内容,以便使用for(auto e:thestack)在堆栈上迭代以自顶向下的方式工作

我发现这显示了两个解决方案,用于反转新for循环语法(以及基于范围的算法)的迭代顺序

我不清楚的是如何提供一个简单的机制,让我的用户能够访问这个自动反转的deque

e、 g.无需任何实际努力,我可以简单地允许const&access访问底层数据:

  const std::deque<T> & GetStack() const { return m_stack; }
在这里,我尝试使用以下解决方案进行反向操作:

template<class Fwd>
struct reverser_generic 
{
    Fwd &fwd;
    reverser_generic(Fwd& fwd_): fwd(fwd_) {}
    typedef std::reverse_iterator<typename Fwd::iterator> reverse_iterator;
    reverse_iterator begin() { return reverse_iterator(std::end(fwd)); } 
    reverse_iterator end() { return reverse_iterator(std::begin(fwd)); } 
};

template<class Fwd>
struct reverser_special
{
    Fwd &fwd;
    reverser_special(Fwd& fwd) : fwd(fwd) { }
    auto begin() -> decltype(fwd.rbegin()) { return fwd.rbegin(); } 
    auto end() -> decltype(fwd.rend()) { return fwd.rend(); } 
};

template<class Fwd>
auto reverse_impl(Fwd& fwd, long) -> decltype(reverser_generic<Fwd>(fwd))
{ 
    return reverser_generic<Fwd>(fwd);
}

template<class Fwd>
auto reverse_impl(Fwd& fwd, int) -> decltype(fwd.rbegin(), reverser_special<Fwd>(fwd))
{ 
    return reverser_special<Fwd>(fwd);
}

template<class Fwd>
auto reverse(Fwd&& fwd) -> decltype(reverse_impl(fwd,int(0))) 
{
    static_assert(!(std::is_rvalue_reference<Fwd&&>::value), "Cannot pass an rvalue reference to reverse()");
    return reverse_impl(fwd,int(0));
}
上述错误,表明m_堆栈未知。此->m_堆栈同样未知

我如何返回“无论是什么,它都是我的成员m_堆栈的反面”


注意,一旦回答了这个问题,我还需要“如何返回反向(m_堆栈)的decltype的const&值”

GetContents
的声明,在
m_堆栈的声明之前

后期指定的返回类型中的名称必须遵守与函数签名其余部分中的名称相同的规则,即它们不能引用尚未声明的类成员:

struct X
{
    auto f() -> decltype(m_x) { return m_x; }  // ERROR
    int m_x;
    auto g() -> decltype(m_x) { return m_x; }  // OK
};

要使其工作,可以使用
std::declval
引用该类型(这意味着如果将
m_堆栈的类型从
std::deque
更改为
std::vector
,则必须更新
GetContents
的签名)或者确保在引用之前已声明了
m\u stack

是否在声明
m\u stack
之前声明了
GetContents

后期指定的返回类型中的名称必须遵守与函数签名其余部分中的名称相同的规则,即它们不能引用尚未声明的类成员:

struct X
{
    auto f() -> decltype(m_x) { return m_x; }  // ERROR
    int m_x;
    auto g() -> decltype(m_x) { return m_x; }  // OK
};

要使其正常工作,可以使用
std::declval
引用该类型(这意味着您必须更新
GetContents
的签名,如果您将
m_stack
的类型从
std::deque
更改为
std::vector
),或者确保在引用它之前声明了
m_stack

decltype(反向(std::declval())
为什么不为类创建合适的迭代器呢?是的,我也遇到过这种情况。懒惰——我走了这条路,现在有点固执地想弄明白这一点。:
std::declval()
?std::declval()的返回类型
X
这是一个右值表达式,但是
std::declval()
的返回类型是
X&
这是一个左值表达式。函数体调用
reverse(m_stack)
并且
m_stack
是一个左值。如果
reverse
函数以不同的方式处理右值和左值,那么
decltype(reverse(std::declval())
的类型与
decltype(reverse(m_stack))
的类型不同,函数将无法编译。更改
std::declval
表达式以给出左值结果将使其与函数体一致。
decltype(reverse(std::declval())
为什么不为您的类创建合适的迭代器呢?是的,我也有过类似的经历。懒惰——我走上这条路后,有点固执地想弄明白这一点。:
std::declval()
?std::declval()的返回类型
X
这是一个右值表达式,但是
std::declval()
的返回类型是
X&
这是一个左值表达式。函数体调用
reverse(m_stack)
并且
m_stack
是一个左值。如果
reverse
函数以不同的方式处理右值和左值,那么
decltype(reverse(std::declval())
的类型与
decltype(reverse(m_stack))的类型不同
,函数将无法编译。更改
std::declval
表达式以给出左值结果,使其与函数体一致。哦!我不知道这会起作用!令人沮丧的是,这里需要这样做,但一旦您知道……我想这没问题。注意,一个特定于延迟的返回类型对于引用o函数参数,但您没有这样做,因此可以同样轻松地编写它
decltype(m_stack)GetContents()const
…那么
m_stack
必须在范围内可能更容易理解,就像您尝试编写
stack\u type GetContents()一样const;
引用一个尚未声明的typedef。哦!我不知道这会起作用!令人沮丧的是,这里需要这样做,但一旦您知道……我想这没关系。注意:引用函数参数可以使用特定于延迟的返回类型,但您没有这样做,因此可以同样轻松地编写
declttype(m_stack)GetContents()const
…那么
m_stack
必须在作用域中可能更容易理解,就像您试图编写
stack\u type GetContents()const;
引用尚未声明的typedef一样。
struct X
{
    auto f() -> decltype(m_x) { return m_x; }  // ERROR
    int m_x;
    auto g() -> decltype(m_x) { return m_x; }  // OK
};