我希望能够为标准库容器实现一个C++概念。
非常感谢您提前的帮助!
非常感谢您提前的帮助!
使用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() } -> 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>;
};
有“容器”概念的前置需求,这个概念大致如下:
template <class E>
concept default_erasable = requires(E * p) {
std::destroy_at(p);
};
template <class E, class T, class A>
concept allocator_erasable = requires(A m, E * p) {
requires std::same_as<typename T::allocator_type, typename std::allocator_traits<A>::rebind_alloc<E>>;
std::allocator_traits<A>::destroy(m, p);
};
template <class T>
concept allocator_aware = requires (T a) {
{ a.get_allocator() } -> std::same_as<typename T::allocator_type>;
};
template <class T>
struct is_basic_string : std::false_type {};
template <class C, class T, class A>
struct is_basic_string<std::basic_string<C, T, A>> : std::true_type {};
template <class T>
constexpr bool is_basic_string_v = is_basic_string<T>::value;
template <class E, class T>
concept erasable = (is_basic_string_v<T> && default_erasable<E>)
|| (allocator_aware<T> && allocator_erasable<E, T, typename T::allocator_type>)
|| (!allocator_aware<T> && default_erasable<E>);
template <class T>
concept container = requires(T a, const T b)
{
requires std::regular<T>;
requires std::swappable<T>;
requires erasable<typename T::value_type, T>;
requires std::same_as<typename T::reference, typename T::value_type &>;
requires std::same_as<typename T::const_reference, const typename T::value_type &>;
requires std::forward_iterator<typename T::iterator>;
requires std::forward_iterator<typename T::const_iterator>;
requires std::signed_integral<typename T::difference_type>;
requires std::same_as<typename T::difference_type, typename std::iterator_traits<typename T::iterator>::difference_type>;
requires std::same_as<typename T::difference_type, typename std::iterator_traits<typename T::const_iterator>::difference_type>;
{ a.begin() } -> std::same_as<typename T::iterator>;
{ a.end() } -> std::same_as<typename T::iterator>;
{ b.begin() } -> std::same_as<typename T::const_iterator>;
{ b.end() } -> std::same_as<typename T::const_iterator>;
{ a.cbegin() } -> std::same_as<typename T::const_iterator>;
{ a.cend() } -> std::same_as<typename T::const_iterator>;
{ a.size() } -> std::same_as<typename T::size_type>;
{ a.max_size() } -> std::same_as<typename T::size_type>;
{ a.empty() } -> std::convertible_to<bool>;
};
您可能希望添加requires std::ranges::range<T>;
以进行概念部分排序。
修正后的版本可以在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>);
std::destructible<typename ContainerType::value_type>
isn't the same as Erasable, empty
is not required to be exactly bool
- Calethvoid a_function(std::ranges::forward_range auto container)
{
...
}
或者另一种选择是...
template<typename T>
concept YourContainer = requires(T container)
{
requires std::ranges::range<T>;
...
};
{ expression } -> typename <TYPE>
似乎无法编译。它可能是在概念标准化之前被删除的特性吗? - BeeOnRope