[英]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.