如何检查模板参数是否为std::vector<T>::iterator
?
对于void类型,我们有std::is_void。是否有类似于std::vector<T>::iterator
的东西?
#include <vector>
#include <list>
#include <type_traits>
template <class T, class = void>
struct is_vector_iterator: std::is_same<T, std::vector<bool>::iterator> { };
template <class T>
struct is_vector_iterator<T, decltype(*std::declval<T>(), std::enable_if_t<!std::is_same<T, std::vector<bool>::iterator>::value>())>: std::is_same<T, typename std::vector<std::decay_t<decltype(*std::declval<T>())>>::iterator> { };
int main() {
static_assert(is_vector_iterator<std::vector<int>::iterator>::value, "Is not a vector iterator");
static_assert(is_vector_iterator<std::vector<bool>::iterator>::value, "Is not a vector iterator");
static_assert(!is_vector_iterator<std::list<int>::iterator>::value, "Is a vector iterator");
static_assert(!is_vector_iterator<std::list<int>::iterator>::value, "Is a vector iterator");
}
is_vector_iterator<std::list<int>::iterator>
,返回true。 - ascheplerstd::vector<bool>::iterator
失败 ;) - Quentinstd::decay_t<decltype(*std::declval<T>())>
而不是直接使用 T::value_type
? - Come Raczyvalue_type
(正如 Bo Persson 建议的那样,甚至允许将其定义为指向所包含类型的指针)... - W.F.另一种解决方案也使用了 std::iterator_traits:
#include <iostream>
#include <vector>
#include <list>
template <typename T>
struct is_vector_iterator
{
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test(
typename std::enable_if<
std::is_same<T, typename std::vector<typename C::value_type>::iterator>::value
>::type*);
template <typename>
static no& test(...);
static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};
int main() {
std::cout << is_vector_iterator<int>::value << std::endl;
std::cout << is_vector_iterator<int*>::value << std::endl;
std::cout << is_vector_iterator<std::list<int>::iterator>::value << std::endl;
std::cout << is_vector_iterator<std::vector<int>::iterator>::value << std::endl;
return 0;
}
std::list<int>::iterator
。目的是确定它是否为 std::vector<T>::iterator
。不仅仅是一个迭代器。 - O'Neil#include <list>
#include <vector>
#include <iterator>
template <class It, class = void>
struct is_vector_iterator : std::false_type { };
template <class It>
struct is_vector_iterator<It, std::enable_if_t<
std::is_same<
It,
typename std::vector<
typename std::iterator_traits<It>::value_type
>::iterator
>::value
>> : std::true_type { };
int main() {
static_assert(is_vector_iterator<std::vector<int>::iterator>::value, "Is not a vector iterator");
static_assert(is_vector_iterator<std::vector<bool>::iterator>::value, "Is not a vector iterator");
static_assert(!is_vector_iterator<std::list<int>::iterator>::value, "Is a vector iterator");
}
std::iterator_traits<It>::value_type
而不是 It::value_type
? - Come Raczystd::vector<T>::iterator
是T*
”,而指针没有value_type
成员。 - O'Neilbool
的情况,其中*std :: declval <It>()
不是bool&
而是代理。 - O'Neilnamespace detail
{
template<typename T> constexpr std::false_type is_vector_iterator(T&&, ...)
{
return {};
}
template<typename T>
constexpr auto is_vector_iterator(T&& t, void* = nullptr) ->
decltype(std::is_same<typename std::vector<std::decay_t<decltype(*t)>>::iterator, std::decay_t<T>>{})
{
return {};
}
}
template<typename T>
struct is_vector_iterator : decltype(detail::is_vector_iterator(declval<T>(), 0)) {};
在这里,我获取了 *t 的衰变类型,以创建 vector<type>::iterator
并检查其是否与 T
相等。它可以正常工作,但是对于 vector<bool>
并不适用,因为它本质上并不是一个向量。
VecIt
,然后验证typename std::vector<typename std::iterator_traits<VecIt>::value_type>::iterator
和VecIt
是否命名为相同的类型,但这并不能保证你得到的东西实际上是一个指向向量的迭代器,因此它并不是那么有用。 - T.C.std::vector<T>::iterator
是T*
。这可能会给你设计的任何测试带来很多误报。 - Bo Persson