【问题标题】:C++20: Concept function, restricted with an archtype takes wider range of inputs, than desiredC ++ 20:概念函数,受架构类型限制,需要比预期更广泛的输入
【发布时间】:2021-08-18 17:34:19
【问题描述】:

给定概念test,它有一个接受输入范围的函数。

template <class T>
concept test = requires(T t, archtypes::Input_Range<T> t_range)
{
    { t.count(t_range) } -> std::same_as<int>;
};

此archtype 允许count 函数成为模板成员函数。

struct Counter1
{
    template<std::ranges::input_range Range>
    int count(const Range&);
}
static_assert(test<Counter1>); // passes

现在这满足了这个概念。但我希望这失败,因为这个范围可以是任何输入范围,而不仅仅是带 int 的输入范围。

只有这样才能通过

struct Counter2
{
    template<std::ranges::input_range Range>
    requires std::is_same_v<int,std::ranges::range_value_t<Range>>
    int count(const Range&);
}
namespace archetypes
{
    // private, only used for concept definitions, NEVER in real code
    template <class T>
    class InputIterator
    {
    public:
        InputIterator();
        ~InputIterator();
        InputIterator(const InputIterator& other);
        InputIterator(InputIterator&& other) noexcept;
        InputIterator& operator=(const InputIterator& other);
        InputIterator& operator=(InputIterator&& other) noexcept;


        using iterator_category = std::input_iterator_tag;
        using value_type = T;
        using reference = T&;
        using pointer = T*;
        using difference_type = std::ptrdiff_t;

        bool operator==(const InputIterator&) const;
        bool operator!=(const InputIterator&) const;
        reference operator*() const;
        InputIterator& operator++();
        InputIterator operator++(int);
    };
    
    template <class T>
    struct Input_Range
    {
        Input_Range(const Input_Range& other) = delete;
        Input_Range(Input_Range&& other) = delete;
        Input_Range& operator=(const Input_Range& other) = delete;
        Input_Range& operator=(Input_Range&& other) = delete;
        ~Input_Range();

        using iterator = InputIterator<T>;

        iterator begin();
        iterator end();
    };
}

我想不出任何改变概念或架构类型的方法,所以Counter1 会失败,但Counter2 会通过。

【问题讨论】:

    标签: c++ templates c++20 c++-concepts std-ranges


    【解决方案1】:

    现在这满足了这个概念。但我希望这失败,因为这个范围可以是任何输入范围,而不仅仅是带 int 的输入范围。

    此要求表示对概念的不当使用。作为一个概念的作者,你的工作是表达你希望用户提供什么界面(从而准确地表达你将使用什么界面)。作为满足该概念的某些类型集的实现者,用户的工作是提供一个在语法和语义上与该概念相匹配的接口。

    根据您的概念,您的代码将仅提供整数范围。 用户 可以允许这个函数接受一系列其他的事情。这是他们的特权,您不应试图干涉。对于这种类型,您的代码仍然可以正常工作,因此没有理由阻止这种情况。

    你的工作不是强制一个类型提供你要求的接口。正如std::ranges::sort 不应该仅仅因为它只要求一个随机访问范围就阻止用户提供一个连续的范围。

    【讨论】:

    • 好吧......我想你是对的,想不出任何反对它的论据。但我仍然很好奇如何做到这一点。
    猜你喜欢
    • 2021-02-16
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多