首页 > 解决方案 > C ++ 20:概念函数,受archtype限制,需要比预期更广泛的输入

问题描述

test给定具有输入范围的功能的概念。

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

此架构类型允许该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++templatesc++20c++-conceptsstd-ranges

解决方案


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

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

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

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


推荐阅读