问题一:
您可以使用以下类型特征:
template<typename T, typename = void>
struct is_const_iterator : std::false_type { };
template<typename T>
struct is_const_iterator<T,
typename std::enable_if<
std::is_const<
typename std::remove_pointer<
typename std::iterator_traits<T>::pointer
>::type
>::value
>::type> : std::true_type { };
这是一个演示:
#include <type_traits>
#include <iterator>
#include <list>
#include <vector>
template<typename T, typename = void>
struct is_const_iterator : std::false_type { };
template<typename T>
struct is_const_iterator<T,
typename std::enable_if<
std::is_const<
typename std::remove_pointer<
typename std::iterator_traits<T>::pointer
>::type
>::value
>::type> : std::true_type { };
int main()
{
typedef std::list<int>::iterator LI;
typedef std::list<int>::const_iterator CLI;
static_assert(is_const_iterator<LI>::value, "!"); // Fires
static_assert(is_const_iterator<CLI>::value, "!"); // Does not fire
typedef std::vector<int>::iterator VI;
typedef std::vector<int>::const_iterator CVI;
static_assert(is_const_iterator<VI>::value, "!"); // Fires
static_assert(is_const_iterator<CVI>::value, "!"); // Does not fire
}
这是一个活生生的例子。
问题2:
使用上述类型特征,这变得很简单。假设您有一个foo()
要约束的函数模板,以便它只接受非const
迭代器:
template<typename It,
typename std::enable_if<!is_const_iterator<It>::value>::type* = nullptr>
void foo(It i)
{
// Does something with i...
}
还有一个简单的演示程序:
int main()
{
std::vector<int> v;
foo(v.begin()); // OK
foo(v.cbegin()); // ERROR!
}
这是一个活生生的例子。