【发布时间】:2020-02-28 10:15:54
【问题描述】:
我想为标准库容器实现一个 C++ 概念。
提前非常感谢!
【问题讨论】:
标签: c++ c++-concepts
我想为标准库容器实现一个 C++ 概念。
提前非常感谢!
【问题讨论】:
标签: c++ c++-concepts
有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<T>
【讨论】:
用 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;
};
【讨论】:
在 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>);
【讨论】: