概念 as_same 身份失败
Concept as_same identity fail
我有一个很好的类型特征来检查类型 T
是否是迭代器:
- 演示:https://wandbox.org/permlink/vUZ2hjQq6i9nlXFd
- 堆栈 post 及解释:
我尝试做同样的事情,但有概念。我的第一次尝试是:
template<typename T>
concept isIterator = requires(T a) {
{ typename std::iterator_traits<T>::difference_type{} } -> std::same_as<typename std::iterator_traits<T>::difference_type>;
{ typename std::iterator_traits<T>::pointer{} } -> std::same_as<typename std::iterator_traits<T>::pointer>;
{ typename std::iterator_traits<T>::value_type{} } -> std::same_as<typename std::iterator_traits<T>::value_type>;
{ typename std::iterator_traits<T>::iterator_category{} } -> std::same_as<typename std::iterator_traits<T>::iterator_category>;
// this line trigger the assert for
// static_assert(is_iterator_v<std::vector<int>::iterator>);
// static_assert(is_iterator_v<int*>);
{ typename std::iterator_traits<T>::reference{} } -> std::same_as<typename std::iterator_traits<T>::reference>;
};
// default case
template <class T>
struct is_iterator : std::false_type
{
};
// specialization
template <isIterator It>
struct is_iterator<It> : std::true_type
{
};
template <class T>
constexpr bool is_iterator_v = is_iterator<T>::value;
演示:https://wandbox.org/permlink/shrJpZPIlS0pXKak
但它失败了:
static_assert(is_iterator_v<std::vector<int>::iterator>);
static_assert(is_iterator_v<int*>);
并继续:
static_assert(is_iterator_v<std::vector<int>::const_iterator>);
static_assert(is_iterator_v<std::list<double>::const_iterator>);
static_assert(!is_iterator_v<std::list<double>>);
static_assert(!is_iterator_v<int>);
我有两个问题:
- 为什么我的概念与
std::vector<int>::iterator
和 int*
不匹配?
static_assert(is_iterator_v<std::vector<int>::const_iterator>);
有效但引用不是默认构造的,那么它如何通过 { typename std::iterator_traits<T>::reference{} }
要求? Thx @cpplearner
注意:我知道我可以做到:
template<typename T>
concept isIterator = requires(T a) {
typename std::iterator_traits<T>::difference_type;
typename std::iterator_traits<T>::pointer;
typename std::iterator_traits<T>::value_type;
typename std::iterator_traits<T>::iterator_category;
typename std::iterator_traits<T>::reference;
};
它的效果很好,但我想了解为什么我的第一次尝试失败了。
它因 std::vector<int>::iterator
和 int*
而失败,因为:
std::iterator_traits<int*>::reference == int&
std::iterator_traits<const int*>::reference == int&
int&{}
不编译(const int&{}
编译)
所以 { typename std::iterator_traits<T>::reference{} }
对这些类型失败。它可以用 :
修复
{ std::declval<typename std::iterator_traits<T>::reference>() } -> std::same_as<typename std::iterator_traits<T>::reference>;
我有一个很好的类型特征来检查类型 T
是否是迭代器:
- 演示:https://wandbox.org/permlink/vUZ2hjQq6i9nlXFd
- 堆栈 post 及解释:
我尝试做同样的事情,但有概念。我的第一次尝试是:
template<typename T>
concept isIterator = requires(T a) {
{ typename std::iterator_traits<T>::difference_type{} } -> std::same_as<typename std::iterator_traits<T>::difference_type>;
{ typename std::iterator_traits<T>::pointer{} } -> std::same_as<typename std::iterator_traits<T>::pointer>;
{ typename std::iterator_traits<T>::value_type{} } -> std::same_as<typename std::iterator_traits<T>::value_type>;
{ typename std::iterator_traits<T>::iterator_category{} } -> std::same_as<typename std::iterator_traits<T>::iterator_category>;
// this line trigger the assert for
// static_assert(is_iterator_v<std::vector<int>::iterator>);
// static_assert(is_iterator_v<int*>);
{ typename std::iterator_traits<T>::reference{} } -> std::same_as<typename std::iterator_traits<T>::reference>;
};
// default case
template <class T>
struct is_iterator : std::false_type
{
};
// specialization
template <isIterator It>
struct is_iterator<It> : std::true_type
{
};
template <class T>
constexpr bool is_iterator_v = is_iterator<T>::value;
演示:https://wandbox.org/permlink/shrJpZPIlS0pXKak
但它失败了:
static_assert(is_iterator_v<std::vector<int>::iterator>);
static_assert(is_iterator_v<int*>);
并继续:
static_assert(is_iterator_v<std::vector<int>::const_iterator>);
static_assert(is_iterator_v<std::list<double>::const_iterator>);
static_assert(!is_iterator_v<std::list<double>>);
static_assert(!is_iterator_v<int>);
我有两个问题:
- 为什么我的概念与
std::vector<int>::iterator
和int*
不匹配? Thx @cpplearnerstatic_assert(is_iterator_v<std::vector<int>::const_iterator>);
有效但引用不是默认构造的,那么它如何通过{ typename std::iterator_traits<T>::reference{} }
要求?
注意:我知道我可以做到:
template<typename T>
concept isIterator = requires(T a) {
typename std::iterator_traits<T>::difference_type;
typename std::iterator_traits<T>::pointer;
typename std::iterator_traits<T>::value_type;
typename std::iterator_traits<T>::iterator_category;
typename std::iterator_traits<T>::reference;
};
它的效果很好,但我想了解为什么我的第一次尝试失败了。
它因 std::vector<int>::iterator
和 int*
而失败,因为:
std::iterator_traits<int*>::reference == int&
std::iterator_traits<const int*>::reference == int&
int&{}
不编译(const int&{}
编译)
所以 { typename std::iterator_traits<T>::reference{} }
对这些类型失败。它可以用 :
{ std::declval<typename std::iterator_traits<T>::reference>() } -> std::same_as<typename std::iterator_traits<T>::reference>;