我正在尝试编写一个类似于的模板函数std::to_string
适用于基本类型以及 STL 容器的迭代器。但我不确定如何编写足够具体的模板来仅识别迭代器。
到目前为止我尝试的是尝试使用iterator
STL 容器中的 typedef
template<typename... Args, template <typename...> class Container>
static string to_string(typename Container<Args...>::iterator s) { ...
下面附有一个最小的例子。代码可以编译但是模板函数My::to_string
无法匹配上述签名,并进行处理std::set<int>::iterator
作为默认类型。
我的问题是如何以通用方式正确编写此代码,以便模板函数My::to_string
可以拾取迭代器,但不要将迭代器与其他标准模板类型混淆,例如std::string
.
提前致谢。
#include <set>
#include <iostream>
using namespace std;
class My{
//base case
template<typename T>
static string to_string(const T& t) {
return "basic ";
}
//specialization for string
template <typename Char, typename Traits, typename Alloc>
static string to_string(const std::basic_string<Char, Traits, Alloc>& s) {
return (string)s;
}
//Problem line: how to write specialization for iterators of standard containers?
template<typename... Args, template <typename...> class Container>
static string to_string(typename Container<Args...>::iterator s) {
return "itor ";
}
};
int main() {
int i = 2;
string str = "Hello";
set<int> s;
s.insert(i);
cout << to_string(i) << ", " << str << ", "
<< to_string(s.begin()) << endl; //didn't get captured by iterator spec.
}
Output:
basic, Hello, basic
期望的输出:
basic, Hello, itor
如果你只关心迭代器性参数的类型,而不是容器的类型,那么您可以使用 SFINAE 输出其他重载。
首先制作一个is_iterator
特质,如图所示这个答案 https://stackoverflow.com/a/11899057/2756719:
template <typename T>
struct sfinae_true : std::true_type {};
struct is_iterator_tester {
template <typename T>
static sfinae_true<typename std::iterator_traits<T>::iterator_category> test(int);
template <typename>
static std::false_type test(...);
};
template <typename T>
struct is_iterator : decltype(is_iterator_tester::test<T>(0)) {};
现在,SFINAE 根据类型是否是迭代器输出错误的重载:
//base case
template<typename T>
static std::enable_if_t<!is_iterator<T>::value, string> to_string(const T& t) {
return "basic ";
}
//specialization for string
template <typename Char, typename Traits, typename Alloc>
static string to_string(const std::basic_string<Char, Traits, Alloc>& s) {
return (string)s;
}
//Problem line: how to write specialization for iterators of standard containers?
template<typename T>
static std::enable_if_t<is_iterator<T>::value, string> to_string(const T& s) {
return "itor ";
}
Demo http://coliru.stacked-crooked.com/a/1d0c1b0e27a7a70d.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)