【问题标题】:How do you define a C++ concept for the standard library containers?您如何为标准库容器定义 C++ 概念?
【发布时间】:2020-02-28 10:15:54
【问题描述】:

我想为标准库容器实现一个 C++ 概念。

提前非常感谢!

【问题讨论】:

    标签: c++ c++-concepts


    【解决方案1】:

    Container 的前置概念要求。作为一个看起来像的概念

    template <class T>
    concept container = requires(T a, const T b)
    {
        requires regular<T>;
        requires swappable<T>;
        requires erasable<typename T::value_type>;
        requires same<typename T::reference, typename T::value_type &>;
        requires same<typename T::const_reference, const typename T::value_type &>;
        requires forward_iterator<typename T::iterator>;
        requires forward_iterator<typename T::const_iterator>;
        requires signed<typename T::difference_type>;
        requires same<typename T::difference_type, typename std::iterator_traits<typename T::iterator>::difference_type>;
        requires same<typename T::difference_type, typename std::iterator_traits<typename T::const_iterator>::difference_type>;
        { a.begin() } -> typename T::iterator;
        { a.end() } -> typename T::iterator;
        { b.begin() } -> typename T::const_iterator;
        { b.end() } -> typename T::const_iterator;
        { a.cbegin() } -> typename T::const_iterator;
        { a.cend() } -> typename T::const_iterator;
        { a.size() } -> typename T::size_type;
        { a.max_size() } -> typename T::size_type;
        { a.empty() } -> boolean;
    };
    

    虽然您想将其中的一些表达为requires range&lt;T&gt;

    【讨论】:

    • 完美 - 谢谢 - 在我看来这似乎很常见我想知道为什么它不是标准的一部分......
    【解决方案2】:

    用 C++ 概念库修正了 Caleth 的答案:

        template <class ContainerType> 
        concept Container = requires(ContainerType a, const ContainerType b) 
        {
            requires std::regular<ContainerType>;
            requires std::swappable<ContainerType>;
            requires std::destructible<typename ContainerType::value_type>;
            requires std::same_as<typename ContainerType::reference, typename ContainerType::value_type &>;
            requires std::same_as<typename ContainerType::const_reference, const typename ContainerType::value_type &>;
            requires std::forward_iterator<typename ContainerType::iterator>;
            requires std::forward_iterator<typename ContainerType::const_iterator>;
            requires std::signed_integral<typename ContainerType::difference_type>;
            requires std::same_as<typename ContainerType::difference_type, typename std::iterator_traits<typename
        _ContainerType_::iterator>::difference_type>;
            requires std::same_as<typename ContainerType::difference_type, typename std::iterator_traits<typename
        _ContainerType_::const_iterator>::difference_type>;
            { a.begin() } -> typename ContainerType::iterator;
            { a.end() } -> typename ContainerType::iterator;
            { b.begin() } -> typename ContainerType::const_iterator;
            { b.end() } -> typename ContainerType::const_iterator;
            { a.cbegin() } -> typename ContainerType::const_iterator;
            { a.cend() } -> typename ContainerType::const_iterator;
            { a.size() } -> typename ContainerType::size_type;
            { a.max_size() } -> typename ContainerType::size_type;
            { a.empty() } -> boolean;
        };
    

    【讨论】:

    • 我想在iterator_traits相关的部分应该没有下划线 _ ContainerType _::iterator ,还是我遗漏了什么?
    【解决方案3】:

    在 C++ 中实际编译的固定版本...:

    template <class ContainerType>
    concept Container = requires(ContainerType a, const ContainerType b)
    {
        requires std::regular<ContainerType>;
        requires std::swappable<ContainerType>;
        requires std::destructible<typename ContainerType::value_type>;
        requires std::same_as<typename ContainerType::reference, typename ContainerType::value_type &>;
        requires std::same_as<typename ContainerType::const_reference, const typename ContainerType::value_type &>;
        requires std::forward_iterator<typename ContainerType::iterator>;
        requires std::forward_iterator<typename ContainerType::const_iterator>;
        requires std::signed_integral<typename ContainerType::difference_type>;
        requires std::same_as<typename ContainerType::difference_type, typename std::iterator_traits<typename ContainerType::iterator>::difference_type>;
        requires std::same_as<typename ContainerType::difference_type, typename std::iterator_traits<typename ContainerType::const_iterator>::difference_type>;
        { a.begin() } -> std::same_as<typename ContainerType::iterator>;
        { a.end() } -> std::same_as<typename ContainerType::iterator>;
        { b.begin() } -> std::same_as<typename ContainerType::const_iterator>;
        { b.end() } -> std::same_as<typename ContainerType::const_iterator>;
        { a.cbegin() } -> std::same_as<typename ContainerType::const_iterator>;
        { a.cend() } -> std::same_as<typename ContainerType::const_iterator>;
        { a.size() } -> std::same_as<typename ContainerType::size_type>;
        { a.max_size() } -> std::same_as<typename ContainerType::size_type>;
        { a.empty() } -> std::same_as<bool>;
    };
    static_assert(Container<std::vector<unsigned char>>);
    static_assert(Container<std::string>);
    

    【讨论】:

    • 这与其他答案有什么区别?如果其他答案有错误,为什么不对它们发表评论?
    猜你喜欢
    • 2023-01-10
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    相关资源
    最近更新 更多