[英]Specialize function to print container contents
我正在讀這個問題:
我試圖修改的一個小40two的回答:
namespace extract
{
template <typename T1, typename T2>
const T2& e(const std::pair<T1, T2>& r)
{
return r.second;
}
template <typename T>
const T& e(const T& r)
{
return r;
}
}
template<typename Iterator>
void print(Iterator begin, Iterator end)
{
while (begin != end)
{
std::cout << extract::e(*begin) << std::endl;
++begin;
}
}
這樣稱呼,工作正常:
std::vector<int> v(3,1);
std::map<int, int> m;
m[0]=10;
m[1]=11;
m[2]=12;
print(v.begin(), v.end());
print(m.begin(), m.end());
我想知道的是,如何只通過begin
而不是*begin
實現同樣的事情?
我想修改當前的e()
函數,讓它們直接重載不同類型的迭代器。
即稱之為:
template<typename Iterator>
void print(Iterator begin, Iterator end)
{
while (begin != end)
{
// NOTE: only pass in begin, please modify e() to let it directly take iterator
std::cout << extract::e(begin) << std::endl;
++begin;
}
}
我認為這更符合原始問題的需要,但我嘗試了很多方法而且無法做到。
謝謝。
你可以用
namespace extract
{
// your current code for e
template <typename IT>
auto e_it(IT&& it) -> decltype (e(*it))
{
return e(*it);
}
}
並將print
更改為
template<typename Iterator>
void print(Iterator begin, Iterator end)
{
while (begin != end)
{
std::cout << extract::e_it(begin) << std::endl;
++begin;
}
}
或者,你可以這樣做
template <typename Iter>
auto
e(Iter it)
-> typename std::enable_if<is_pair<typename std::iterator_traits<Iter>::value_type>::value,
decltype(it->second)>::type
{
return it->second;
}
template <typename Iter>
auto
e(Iter it)
-> typename std::enable_if<!is_pair<typename std::iterator_traits<Iter>::value_type>::value,
decltype(*it)>::type
{
return *it;
}
這對我來說似乎不太清楚。
實例 。
您可以定義is_iterator
特征:
template <class, class Enable = void> struct is_iterator : std::false_type {};
template <typename T> struct is_iterator<T, typename std::enable_if<std::is_pointer<typename std::iterator_traits<T>::pointer>::value>::type> : std::true_type {};
然后在SFINAE的幫助下,定義print_elem
重載,如下所示:
namespace detail {
template<typename T1, typename T2>
std::ostream& print_elem(std::ostream &out, std::pair<T1, T2> const &mp) {
return (out << "(" << mp.first << ", " << mp.second << ")");
}
template<typename T>
std::ostream& print_elem(std::ostream &out, T const &elem, typename std::enable_if<!is_iterator<T>::value>::type* = nullptr) {
return (out << elem);
}
template<typename T>
std::ostream& print_elem(std::ostream &out, T const &elem, typename std::enable_if<is_iterator<T>::value>::type* = nullptr) {
return print_elem(out, *elem);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.