CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Aug 2008
    Posts
    902

    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>]’

  2. #2
    Join Date
    Aug 2008
    Posts
    902

    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.

  3. #3
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    Aug 2008
    Posts
    902

    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.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Boost Lexical Cast

    Quote 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:etail::tvec2<T> to read from input streams, it is best to do so within the glm:etail namespace. Unfortunately, that namespace is reserved, by convention, to GLM developers working on GLM implementation detail.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured