首页 > 解决方案 > 如何确定迭代器在c ++模板函数中指向的对象的类型?

问题描述

我在 C++ 中有一个模板函数,可以序列化一个可迭代的:

template<typename Stream, typename Iter, typename Infix, typename Closure>
inline Stream &stream_iterable(Stream &os, Iter from, Iter to, Infix infix_, Closure open, Closure close) {
    if (from == to) return os;
    os << open << *from;
    for (++from; from != to; ++from) {
        os << infix_ << *from;
    }
    os << close;
    return os;
}

例如,它基本上转换std::vector<int>{1,2}为字符串"[1,2]"

我想检查迭代器指向的对象的类型,如果是std::string,我想使用std::quoted在向量的元素周围添加引号,像这样:

template<typename Stream, typename Iter, typename Infix, typename Closure>
inline Stream &steam_iterable_quoted(Stream &os, Iter from, Iter to, Infix infix_, Closure open, Closure close) {
    if (from == to) return os;
    os << open << std::quoted(*from);
    for (++from; from != to; ++from) {
        os << infix_ << std::quoted(*from);
    }
    os << close;
    return os;
}

如何检查 (*from) 的类型并将这两个函数合二为一?

标签: c++templatesvectorc++14

解决方案


您实际上不需要知道stream_iterable. 就像老话说的那样,添加一个间接级别:

namespace detail {
  template<typename T>
  constexpr T const& prepare_to_print(T const& t) { return t; }

  auto prepare_to_print(std::string const s&) { return std::quoted(s); }
  // A non-const overload would be required as well...
  // Forwarding can be a drag sometimes 
}

只需将取消引用的迭代器传递给prepare_to_print. 重载的好处是您可以通过稍后添加更多来进一步自定义行为。


推荐阅读