Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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++_Stl_Iterator_C++14_Const Iterator - Fatal编程技术网

C++ c++;范围的排序视图-如何创建常量迭代器?

C++ c++;范围的排序视图-如何创建常量迭代器?,c++,stl,iterator,c++14,const-iterator,C++,Stl,Iterator,C++14,Const Iterator,我正在尝试编写一个类,该类应该充当一些底层元素序列的排序视图。到目前为止,我已经提出了一个非const版本。现在,我在调整它以提供const\u迭代器功能方面遇到了问题 到目前为止,我的代码如下所示: // forward declare iterator template <class InputIt> class sorted_range_iter; template <class InputIt> class sorted_range { friend c

我正在尝试编写一个类,该类应该充当一些底层元素序列的排序视图。到目前为止,我已经提出了一个非
const
版本。现在,我在调整它以提供
const\u迭代器
功能方面遇到了问题

到目前为止,我的代码如下所示:

// forward declare iterator
template <class InputIt>
class sorted_range_iter;

template <class InputIt>
class sorted_range {
    friend class sorted_range_iter<InputIt>;

  private:
    using T = typename InputIt::value_type;
    InputIt _first;
    InputIt _last;
    std::vector<size_t> _indices;

  public:
    using iterator = sorted_range_iter<InputIt>;

    sorted_range() = default;
    sorted_range(InputIt first, InputIt last)
        : _first(first), _last(last), _indices(std::distance(_first, _last)) {
        std::iota(_indices.begin(), _indices.end(), 0);
    };

    template <class Compare = std::less<T>>
    void sort(Compare comp = Compare()) {
        std::sort(_indices.begin(), _indices.end(),
                  [this, &comp](size_t i1, size_t i2) {
                      return comp(*(_first + i1), *(_first + i2));
                  });
    }

    size_t size() const { return _indices.size(); }
    T& operator[](size_t pos) { return *(_first + _indices[pos]); }
    const T& operator[](size_t pos) const { return (*this)[pos]; }

    iterator begin() { return iterator(0, this); }
    iterator end() { return iterator(size(), this); }
};
template <class InputIt>
class sorted_range_iter
    : public std::iterator<std::forward_iterator_tag, InputIt> {

    friend class sorted_range<InputIt>;

  private:
    using T = typename InputIt::value_type;

    size_t _index;

    sorted_range<InputIt>* _range;
    sorted_range_iter(size_t index, sorted_range<InputIt>* range)
        : _index(index), _range(range) {}

  public:
    T& operator*() { return *(_range->_first + _range->_indices[_index]); }

    // pre-increment
    const sorted_range_iter<InputIt>& operator++() {
        _index++;
        return *this;
    }

    // post-increment
    sorted_range_iter<InputIt> operator++(int) {
        sorted_range_iter<InputIt> result = *this;
        ++(*this);
        return result;
    }

    bool operator!=(const sorted_range_iter<InputIt>& other) const {
        return _index != other._index;
    }
};
std::vector<int> t{5, 2, 3, 4};
auto rit = ref.begin();
sorted_range<std::vector<int>::iterator> r(begin(t), end(t));
r.sort();

for(auto& x : r)
{
    std::cout << x << std::endl;
}
如何使迭代器适应
const
情况?如果迭代器以底层类型(
int
为例)为模板,而不是
InputIt
为模板,则更容易实现。有没有更好的方法来定义这个类


例如,我想可以通过使用库来解决这个问题,但是我尝试不添加任何依赖项,而是依赖C++11/14函数。

您只是对
T
使用了错误的类型。你有:

using T = typename InputIt::value_type;
但是
value\u type
对于
iterator
const\u iterator
是相同的。它们有不同的引用类型。您应该更喜欢:

using R = typename std::iterator_traits<InputIt>::reference;

R operator*() { ... }


旁注,
sorted\u range
不应该在构造上对自身进行排序吗?否则,容易误用

啊,这很有道理,非常感谢!需要显式调用
sort
的原因是,我希望能够完全控制何时执行排序,因为这可能是一个非常昂贵的函数调用。我还有一个有点相关的问题:现在我需要将排序范围声明为:
sorted\u range
。最好,我只想说
sorted\u range
。有办法做到这一点吗?@j.dog没有,您需要迭代器类型。您可以只制作一个函数
sorted\u range make\u sorted\u range(T,T)这样您就不必自己拼写迭代器类型。
using R = typename std::iterator_traits<InputIt>::reference;

R operator*() { ... }
using R = decltype(*std::declval<InputIt>());