繁体   English   中英

如何确定C ++模板函数中迭代器指向的对象的类型?

[英]How to determine the type of the object an iterator is pointing to in c++ template function?

我在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)的类型并将这两个函数合并为一个?

您实际上不需要知道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 关于重载的好处是您可以在以后添加更多的行为来进一步自定义行为。

这个最简单的工作版本:

namespace quoting {
  template<class T>
  T const& auto_quote( T const& t ) { return t; }
  template<class C, class T>
  auto auto_quote( std::basic_string<C,T> const& s ) {
    return std::quoted(s);
  }
  // add more std types that need quoting here.
}

现在执行此操作:

// ...
if (from == to) return os;
using quoting::auto_quote;
os << open << auto_quote(*from);
for (++from; from != to; ++from) {
    os << infix_ << auto_quote(*from);
}
os << close;
// ...

为了使事情有不同的报价,覆盖auto_quote的类型的命名空间(如果不是std ;没有注入到名字std允许)或namespace quoting 它将被自动提取。

因此,如果您的my_string在名称空间my_ns

namespace my_ns {
  auto auto_quote( my_string const& s ) {
    // some manual quoting code
  }
}

它将被上述代码自动提取。

您可以使用decltype(*from)获得解引用运算符的结果类型,但是(1)在进行比较之前,可能需要对其进行进一步处理(它可能是一个引用,一个值,可能是cv限定的,... ),以及(2)并不是真正可扩展的WRT其他类型。

通常,对于此类内容,您想委托给一个模板函数(在您的情况下),该函数负责在流上实际输出数据,默认情况下为“正常”类型,并将其专门化为需要特殊处理的类型治疗。

使用它来检索迭代器引用的对象的类型: std::iterator_triats<SomeIteratorType>::value_type

要组合这两个函数,可以使用constexpr if语句,它是C ++ 17的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM