网站建站的书籍,企业咨询属于什么行业,做百度移动网站点击软,杭州网站建设seo许多时候#xff0c;我们想要直接打印容器的内容#xff0c;比如 std::vectorint a { 1, 2, 3 }; 可以打印出[1, 2, 3]。 参考标准库#xff0c;可以写出一个带有迭代器的to_string函数#xff1a; template typename Iter, typename Func
std::string to…许多时候我们想要直接打印容器的内容比如 std::vectorint a { 1, 2, 3 }; 可以打印出[1, 2, 3]。 参考标准库可以写出一个带有迭代器的to_string函数 template typename Iter, typename Func
std::string to_string(Iter begin, Iter end, Func func) {std::string str;str.append([);if (begin ! end) {str.append(func(*begin));while (begin ! end) {str.append(, );str.append(func(*begin));}}str.append(]);return str;
}在调用时候可以直接传入begin()和end()作为迭代器再传入对于元素的to_string函数即可实现容器的to_string。 std::to_string是C11新增的标准库中定义的函数具有多个重载函数详情请参考to_string - CReference string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val); 由于是重载函数因此不能直接使用名称to_string进行函数的传递。 我们想要使用类似于to_string(vec.begin(), vec.end(), to_string)这种传递方式怎么办呢 在C11中我们可以传递匿名函数lambda解决二义性问题 用 [](const T t) { return to_string(t); } 取代 to_string。 to_string(vec.begin(), vec.end(), [](const T t) { return to_string(t); });还有一种方法就是定义函数对象 template typename T
struct ToString
{std::string operator()(const T t){return to_string(t);}
};to_string(vec.begin(), vec.end(), ToStringT());这在C11标准之前的代码中经常使用。 借此我们可以定义一个vector版的to_string函数 template typename T
std::string to_string(const std::vectorT vec)
{return to_string(vec.begin(), vec.end(),[](const T t) { return to_string(t); });} // Or template typename T
std::string to_string(const std::vectorT vec)
{return to_string(vec.begin(), vec.end(), ToStringT());
}然后就可以这么使用了 std::vectorint a { 1, 2, 3 };std::vectorint b { 4, 5, 6 };std::vectorstd::vectorint c { a, b };std::cout to_string(a) std::endl; // [1, 2, 3]std::cout to_string(b) std::endl; // [4, 5, 6]std::cout to_string(c) std::endl; // [[1, 2, 3], [4, 5, 6]]可以输出vector的各种类型包括vector。 然而存在一个问题就是由于我的这些代码在最初就using namespcae std;了因此并没有什么问题出现很好地实现了vector类型的to_string重载。 但是当我们把该行去掉后就会发现编译器会报出错误。 比如在ToString类的operator()函数中在 return to_string(t); 这一行就报出了 error: no matching function for call to to_string(const int) 的错误。 似乎解决方法很简单直接加std::不就行了吗 然而我们发现这种解决方法在只输出a和b的情况下确实没什么问题但是当输出c的时候又报出了 error: no matching function for call to to_string(const std::vectorint) 的错误。 ——怎么办呢 其实解决起来很简单就是使用using使得命名空间无效当然这个using是加在函数里面的。 template typename T
struct ToString
{std::string operator()(const T t){using std::to_string; // 标准库to_stringusing ::to_string; // 自定义to_stringreturn to_string(t);}
};using ::to_string表示你自定义to_string的位置如果也是在命名空间里面如namespace A那么就写成using A::to_string;即可。 完整代码如下 #include iostream
#include string
#include vectortemplate typename Iter, typename Func
std::string to_string(Iter begin, Iter end, Func func) {std::string str;str.append([);if (begin ! end) {str.append(func(*begin));while (begin ! end) {str.append(, );str.append(func(*begin));}}str.append(]);return str;
}template typename T
struct ToString;template typename T
std::string to_string(const std::vectorT vec)
{return to_string(vec.begin(), vec.end(), ToStringT());// Or/*return to_string(vec.begin(), vec.end(),[](const T t) {using std::to_string;using ::to_string;return to_string(t);});*/
}template typename T
struct ToString
{std::string operator()(const T t){using std::to_string;using ::to_string;return to_string(t);}
};int main(void)
{std::vectorint a { 1, 2, 3 };std::vectorint b { 4, 5, 6 };std::vectorstd::vectorint c { a, b };std::cout to_string(c) std::endl;return 0;
}转载于:https://www.cnblogs.com/chillmagic/p/5713773.html