October 26th, 2011 08:48 AM
#1
Boost Lexical Cast
I'm having issues with boost::lexical_cast. I am trying to use it on a class from the GLM (OpenGL Mathematics) library.
To allow for lexical casting, I have implemented operator<< functions for the class in question:
Code:
template <class T>
std::ostream& operator<<(std::ostream& out, const glm::detail::tvec2<T>& vec)
{
out << vec.x << " " << vec.y;
return out;
}
template <class T>
std::istream& operator>>(std::istream& in, glm::detail::tvec2<T>& vec)
{
in >> vec.x;
in >> vec.y;
return in;
}
I tested the operators like so:
Code:
std::cout << glm::ivec2(1, 1) << glm::vec2(1.0f, 1.0f);
This works just fine, however if I try this:
Code:
glm::ivec2 pt = boost::lexical_cast<glm::ivec2>("1 1");
I get the following error:
Code:
/usr/include/boost/lexical_cast.hpp: In member function ‘bool boost::detail::lexical_stream_limited_src<CharT, Base, Traits>::operator>>(InputStreamable&) [with InputStreamable = glm::detail::tvec2<int>, CharT = char, Base = std::basic_streambuf<char>, Traits = std::char_traits<char>]’:
/usr/include/boost/lexical_cast.hpp:1151:13: instantiated from ‘Target boost::detail::lexical_cast(typename boost::call_traits<B>::param_type, CharT*, std::size_t) [with Target = glm::detail::tvec2<int>, Source = const char*, bool Unlimited = false, CharT = char, typename boost::call_traits<B>::param_type = const char* const, std::size_t = long unsigned int]’
/usr/include/boost/lexical_cast.hpp:1174:77: instantiated from ‘Target boost::lexical_cast(const Source&) [with Target = glm::detail::tvec2<int>, Source = char [8]]’
test2.cpp:41:59: instantiated from here
/usr/include/boost/lexical_cast.hpp:785:29: error: cannot bind ‘std::basic_istream<char>’ lvalue to ‘std::basic_istream<char>&&’
/usr/include/c++/4.6/istream:852:5: error: initializing argument 1 of ‘std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&&, _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = glm::detail::tvec2<int>]’
October 27th, 2011 12:11 AM
#2
Re: Boost Lexical Cast
Here is a minimal example of what replicates the error:
Code:
#include <glm/glm.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/ptree.hpp>
template <class T>
std::ostream& operator<<(std::ostream& out, const glm::detail::tvec2<T>& vec)
{
out << vec.x << " " << vec.y;
return out;
}
template <class T>
std::istream& operator>>(std::istream& in, glm::detail::tvec2<T>& vec)
{
in >> vec.x;
if (in.good() && in.ignore(256, ' ').good())
in >> vec.y;
return in;
}
int main()
{
glm::ivec2 pt = boost::lexical_cast<glm::ivec2>("640 480");
}
If I remove the Boost.PropertyTree header file, it will compile. I posted this on some other sites as well, and so far nobody has any clue.
October 27th, 2011 01:43 AM
#3
Re: Boost Lexical Cast
I can confirm the error with Boost 1.47.0 and GLM 0.9.2.7 when compiling on g++ 4.4.5 using your test program. A "manual" version that uses a stringstream directly works even with the Boost.PropertyTree header file included, so my guess is that this is a bug with boost::lexical_cast.
October 27th, 2011 01:50 AM
#4
Re: Boost Lexical Cast
Oh, on a hunch, from a past discussion on the Boost developers list concerning an input manipulator I once proposed, I suspected that argument dependent lookup was working against you, and a quick check seems to show that I am right. Try:
Code:
#include <glm/glm.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/ptree.hpp>
namespace glm
{
namespace detail
{
template <class T>
std::ostream& operator<<(std::ostream& out, const glm::detail::tvec2<T>& vec)
{
out << vec.x << " " << vec.y;
return out;
}
template <class T>
std::istream& operator>>(std::istream& in, glm::detail::tvec2<T>& vec)
{
in >> vec.x;
if (in.good() && in.ignore(256, ' ').good())
in >> vec.y;
return in;
}
}
}
int main()
{
glm::ivec2 pt = boost::lexical_cast<glm::ivec2>("640 480");
}
As such, it is not a bug with lexical_cast. My bad.
October 27th, 2011 01:55 AM
#5
Re: Boost Lexical Cast
I have no idea (yet) what argument dependent lookup is, but that sure seems to be the problem and solution.
Thank you very much for coming up with that. I could have been tearing my hair out for days.
October 27th, 2011 02:33 AM
#6
Re: Boost Lexical Cast
Originally Posted by
Chris_F
I have no idea (yet) what argument dependent lookup is, but that sure seems to be the problem and solution.
Basically, as the call of operator>> within lexical_cast is unqualified, the name lookup also considers namespaces that the types of the arguments are from. As such, to overload operator>> for glm::detail::tvec2<T> to read from input streams, it is best to do so within the glm::detail namespace. Unfortunately, that namespace is reserved, by convention, to GLM developers working on GLM implementation detail.
Posting Permissions
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Rules
Click Here to Expand Forum to Full Width
Bookmarks