2016-08-30 111 views
9

這是一個包含boost::circular_bufferstruct的類。我爲包含circular_buffer的迭代器製作了一個typedef。std :: upper_bound在const成員函數中返回const迭代器

我的問題是這樣的:當doWork功能標記conststd::upper_bound返回值是不符合MyIterator型由於有boost::cb_details::const_traits返回值兼容。如果我從該函數中刪除const關鍵字,那麼我所有的編譯錯誤都會消失。

要明確編譯器錯誤是這樣的:

error: conversion from ‘boost::cb_details::iterator<boost::circular_buffer<Wrapper<int>::Sample, std::allocator<Wrapper<int>::Sample> >, boost::cb_details::const_traits<std::allocator<Wrapper<int>::Sample> > >’ to non-scalar type ‘Wrapper<int>::MyIterator {aka boost::cb_details::iterator<boost::circular_buffer<Wrapper<int>::Sample, std::allocator<Wrapper<int>::Sample> >, boost::cb_details::nonconst_traits<std::allocator<Wrapper<int>::Sample> > >}’ requested  
          [](const Sample& a, const Sample& b) { return a.foo < b.foo; }); 

這裏是一個自包含的例子:

#include <algorithm> 
#include <boost/circular_buffer.hpp> 

template <typename T> 
class Wrapper { 
public: 
    struct Sample { 
     T foo; 
    }; 

    typedef typename boost::circular_buffer<Sample>::iterator MyIterator; 

    Wrapper(int size) { cb.resize(size); } 

    void add(T val) { cb.push_back(Sample{val}); } 

    void doWork(T bound) const { 
     MyIterator iter = 
      std::upper_bound(cb.begin(), cb.end(), Sample{3}, 
         [](const Sample& a, const Sample& b) { return a.foo < b.foo; }); 
    } 

    boost::circular_buffer<Sample> cb; 
}; 

int main() { 
    Wrapper<int> buf(100); 
    buf.add(1); 
    buf.add(5); 
    buf.doWork(3); 
    return 0; 
} 

那麼,爲什麼不能這個功能是const?爲什麼標記它有這個副作用?我想要一個非const的迭代器到容器中,但在我真正的測試用例中,我根本不打算真正修改容器。

+4

既然'doWork'是'const','cb'也被當作'const'處理。由於'doWork'並不打算修改'cb',而是使用'const_iterator'。 –

+2

MCVE!奇蹟永遠不會停止。 +1 –

+1

@CaptainObvlious:答案部分在下面,朋友 –

回答

7

您將需要一個const_iterator,因爲您正在有效地觀察const容器。

也許:

typedef typename boost::circular_buffer<Sample>::const_iterator MyConstIterator; 

&hellip;然後製作iter其中之一。

有人會告訴你,你可以用auto來避免這種情況。這是真的,但是你永遠不會發現這個「bug」,或者存在。

+0

確實現在我明白了const_iterators,謝謝! – Chris

4

如果你的函數被標記爲const那麼你對成員變量的所有訪問也將是const

A const容器只允許訪問const_迭代器,這就是迭代器的工作方式。