如何解决C++20:受archtype限制的概念函数需要比预期更广泛的输入
template <class T>
concept test = requires(T t,archtypes::Input_Range<T> t_range)
{
{ t.count(t_range) } -> std::same_as<int>;
};
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
会通过。
解决方法
现在这满足了这个概念。但我希望这失败,因为这个范围可以是任何输入范围,而不仅仅是带 int 的输入范围。
此要求代表对概念的不当使用。作为一个概念的作者,你的工作是表达你期望用户提供什么界面(以及你将使用什么界面)。作为实现该概念的某些类型集的实现者,用户的工作是提供一个在语法和语义上与该概念相匹配的接口。
根据您的概念,您的代码将仅提供一系列整数。 用户 可以允许此函数执行一系列其他操作。这是他们的特权,你不应该试图干涉这一点。您的代码对于这种类型仍然可以正常工作,因此没有理由阻止这种情况。
你的工作不是强制一个类型只提供你要求的接口。正如 std::ranges::sort
不应该仅仅因为用户只要求随机访问范围而阻止用户提供连续范围。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。