【问题标题】:Using std::conditional with iterator使用带有迭代器的 std::conditional
【发布时间】:2021-07-24 13:06:06
【问题描述】:

在“掌握 C++17 STL”一书中,我在一个类中看到了迭代器和 const_iterator 实现,使用条件来减少代码重复

这是我对简单数组类的实现(跳过了大多数数组类的代码):

template<class T, size_t N>
class Array
{
public:
    template<bool Const>
    class ArrayIterator {
        friend class Array;
    public:
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = std::conditional<Const, const value_type*, value_type*>;
        using reference = std::conditional<Const, const value_type&, value_type&>;
        using iterator_category = std::random_access_iterator_tag;

        reference operator*() const { return *ptr; }
        ArrayIterator<Const>& operator++() { ++ptr; return *this; }
        ArrayIterator<Const> operator++(int) { auto res = *this; ++(*this); return res; }

        template<bool R>
        bool operator==(const ArrayIterator<R>& iter) const { return ptr == iter.ptr; }
        template<bool R>
        bool operator!=(const ArrayIterator<R>& iter) const { return ptr != iter.ptr; }

    private:
        explicit ArrayIterator(pointer p) : ptr(p) {};
        pointer ptr;
    };

    using iterator = ArrayIterator<false>;
    using const_iterator = ArrayIterator<true>;
    iterator begin() { return iterator(data); }
    iterator end() { return iterator(data + N); }
    const_iterator cbegin() const { return const_iterator(data); }
    const_iterator cend() const { return const_iterator(data + N); }

private:
    T* data;
};

这段代码编译没有错误,但迭代器有点不可用:

Array<int, 100> arr;
/*filling it with numbers*/
int x = *arr.begin(); 

给出错误:

main.cpp:9:9: error: no viable conversion from 'Array<int, 100>::ArrayIterator<false>::reference' (aka 'conditional<false, const int &, int &>') to 'int'

我该如何使用那个迭代器,还是应该从书中放弃这个想法?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    ArrayIterator 的成员类型pointerreference 应定义为std::conditional 的成员类型type,而不是std::conditional 本身。

    将它们更改为:

    using pointer = typename std::conditional<Const, const value_type*, value_type*>::type;
    //              ^^^^^^^^                                                        ^^^^^^
    using reference = typename std::conditional<Const, const value_type&, value_type&>::type;
    //                ^^^^^^^^                                                        ^^^^^^
    

    或(C++14 起)

    using pointer = std::conditional_t<Const, const value_type*, value_type*>;
    //                              ^^  
    using reference = std::conditional_t<Const, const value_type&, value_type&>;
    //                                ^^  
    

    【讨论】:

    • 谢谢,由于某种原因我没有 conditional_t(但我有类似 C++17 的文件系统库)
    • @crends 它减少了打字,here 是它的定义,如果你愿意,你可以做一个。
    猜你喜欢
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 2020-03-24
    • 1970-01-01
    • 2023-03-05
    • 2020-12-23
    相关资源
    最近更新 更多