Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 专门化函数以打印容器内容_C++_C++11 - Fatal编程技术网

C++ 专门化函数以打印容器内容

C++ 专门化函数以打印容器内容,c++,c++11,C++,C++11,我在读这个问题: 我试着修改了一些作者的答案: 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&

我在读这个问题:

我试着修改了一些作者的答案:

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;
    }
}
我认为这会更符合原始问题的需要,但我尝试了很多方法,但都没能做到

谢谢。

您可以使用

namespace extract
{
    // your current code for e

    template <typename IT>
    auto e_it(IT&& it) -> decltype (e(*it))
    {
        return e(*it);
    }
}

或者,你也可以这样做

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;
}
模板
汽车
国际热核实验堆(Iter-it)
->typename std::enable_ifsecond)>::type
{
返回->秒;
}
模板
汽车
国际热核实验堆(Iter-it)
->typename std::enable_if::value_type>::value,
decltype(*it)>::type
{
归还它;
}
这对我来说似乎不太清楚


.

您可以定义一个
is\u迭代器
特征:

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 {};

我们的目标是保留原来的
e
函数,并拥有一个新的
e
函数来使用迭代器吗?然后,您可能想阅读有关(并且可能)的内容。目标是使调用站点看起来像
extract::e(begin)
,以便
e
使用迭代器。欢迎修改
e
以适应此目标!您好,很抱歉我没有把问题讲清楚,是否可以直接重载我的
e
来使用不同类型的迭代器?我的意思是,我可以删除我当前的
e
,让新的
e
直接使用迭代器。我修改了我的问题,如果可能,请重新阅读,谢谢!它实际上不可能实现您想要的功能,因为函数模板无法从
std::vector::iterator
这样的类型推断其参数,因为
T
出现在不可推断的上下文中。这意味着您需要有一个函数模板,使用上面的迭代器,如
e_it
(但如果这让您更快乐,请将其重命名为
e
),并调用原始的
e
(如果这让您更快乐,请将其重命名为
e_impl
),以区分
pair
和其他值类型。@JonathanWakely我明白了。关于为什么它是不可推断的,有什么参考资料可以阅读吗?(或者谷歌关键词可以)我想知道更多细节,谢谢@MarsonMao:刚刚编辑了一个只有
e
和typetraits的解决方案,它与402的实现相匹配。
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;
}
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 {};
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);
  }
}