Boost :: lexical_cast and structure of non-strict types

I have (maybe) a simple problem with boost :: lexical_cast with composite types (in my case std::vector .

My first version of the patterned line function was as follows

 template <typename T> std::string stringiy(const T &t) { std::ostringstream o; o<< t; return o.str(); } 

and working example:

 vector<int> x(10,-3; cout << stringify<vector<int> >(x) << endl; 

with output "-3-3-3-3-3-3-3-3"~ but for performance reasons I want to use boost::lexical_cast

Now I have changed the implementation of the function:

 template <typename T> std::string stringiy(const T &t) { return boost::lexical_cast<string>(t); } 

while this method works for built-in types, it stops working for cases like the previous one when it is used for std::vector

The problem remains (it does not compile) if you create a specialized template for vectors

 template <typename T> std::string stringiy(const std::vector<T> &t) { vector<string> strret = num2str(t); string r; for ( vector<string>::iterator iter = strret.begin(); iter!=strret.end(); ++iter ) r.append(*iter); return r; } 

Any suggestion?

g ++ - 4.5, ubuntu 11.10 amd64

 In file included from Util.h:41:0, from testLexicalCast.cpp:49: /usr/include/boost/lexical_cast.hpp: In member function 'bool boost::detail::lexical_stream<Target, Source, Traits>::operator<<(const Source&) [with Target = std::basic_string<char>, Source = std::vector<double>, Traits = std::char_traits<char>]': /usr/include/boost/lexical_cast.hpp:1151:13: instantiated from 'Target boost::detail::lexical_cast(typename boost::call_traits<Source>::param_type, CharT*, size_t) [with Target = std::basic_string<char>, Source = std::vector<double>, bool Unlimited = true, CharT = char, typename boost::call_traits<Source>::param_type = const std::vector<double>&, size_t = long unsigned int]' /usr/include/boost/lexical_cast.hpp:1174:77: instantiated from 'Target boost::lexical_cast(const Source&) [with Target = std::basic_string<char>, Source = std::vector<double>]' Util.h:211:43: instantiated from 'std::string util::stringify(const T&) [with T = std::vector<double>, std::string = std::basic_string<char>]' testLexicalCast.cpp:72:53: instantiated from here /usr/include/boost/lexical_cast.hpp:595:48: error: no match for 'operator<<' in '((boost::detail::lexical_stream<std::basic_string<char>, std::vector<double>, std::char_traits<char> >*)this)->boost::detail::lexical_stream<std::basic_string<char>, std::vector<double>, std::char_traits<char> >::stream << input' /usr/include/c++/4.5/ostream:108:7: note: candidates are: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:117:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ios_type& (*)(std::basic_ostream<_CharT, _Traits>::__ios_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>, std::basic_ostream<_CharT, _Traits>::__ios_type = std::basic_ios<char>] /usr/include/c++/4.5/ostream:127:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:165:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:169:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:173:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/bits/ostream.tcc:91:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>] /usr/include/c++/4.5/ostream:180:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/bits/ostream.tcc:105:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>] /usr/include/c++/4.5/ostream:191:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:200:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:204:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:209:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:213:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:221:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/ostream:225:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] /usr/include/c++/4.5/bits/ostream.tcc:119:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__streambuf_type*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>] make: *** [testLexicalCast.o] Error 1 
+4
source share
2 answers

You probably specified your operator<< vector for vectors in the global namespace, and boost::lexical_cast will only look in the boost:: namespace and in the std:: , where ostream defined. Try adding your overload to the std:: namespace by wrapping the declaration and definition of operator<< in namespace std { ... } .

+6
source

I may be here, but personally, I think that it will be better for you, rather than trying to create a container that you create for all containers using the "serialize" method.

EDIT: FIXED

 template<typename Container> std::string serialize_container(const Container& container) { std::stringstream ss; std::copy(container.begin(), container.end(), std::ostream_iterator<typename Container::value_type>(ss,"-")); return ss.str(); } 

EDIT: if you want to use a vector with stringify then you will do it like this.

 template <typename T, typename A=void> std::string stringiy(const T& t) { //... } template <typename T, typename A> std::string stringiy(const std::vector<T, A>& container) { std::stringstream ss; //if << is overloaded for vector ss << container; /*//else std::copy(container.begin(), container.end(), std::ostream_iterator<T>(ss,"-")); // std::ostream_iterator<typename Container::value_type>(ss,"-")); */ return ss.str(); } 

NB untested, but that's the point.

+1
source

Source: https://habr.com/ru/post/1386118/


All Articles