問題1:
你可以使用下列類型的特點:
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
}
這裏是一個live example。
問題2:
利用上述類型的性狀,這變得簡單。假設你有要約束,使其只接受非const
迭代函數模板foo()
:
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!
}
這裏是一個live example。
你可以從['std :: is_const'](http://en.cppreference.com/w/cpp/types/is_const)開始。 –
BoBTFish
2013-05-11 15:26:32
@BoBTFish我試過了,但不起作用。 'const_iterator'和'const iterator'是兩個不同的東西。試試這個:http://pastebin.com/kKQEQthj – Sheljohn 2013-05-11 15:33:55
@BoBTFish對不起,你是否編輯了你的評論?我可以發誓我沒有看到'decltype(* it)'當我發佈我的最後一條評論時..你也會對我也是這樣:) – Sheljohn 2013-05-11 15:49:46