Как мне заставить Boost.LexicalCast работать? - PullRequest
0 голосов
/ 26 октября 2011

У меня проблемы с boost :: lexical_cast.Я пытаюсь использовать его в классе из библиотеки GLM (OpenGL Matmatics).

Для обеспечения лексического приведения я реализовал функции operator << для рассматриваемого класса: </p>

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;
}

Я проверил операторы так:

std::cout <<  glm::ivec2(1, 1) << glm::vec2(1.0f, 1.0f);

и:

std::stringstream ss("640 480");
glm::ivec2 pt;
ss >> pt;
std::cout << pt << std::endl;

Это прекрасно работает, однако, если я попробую это:получить следующую ошибку:

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

РЕДАКТИРОВАТЬ: Кажется, ошибка возникает, только если включены заголовки для Boost.PropertyTree.

Ответы [ 2 ]

1 голос
/ 27 октября 2011

Ответ был найден другим, поэтому я оставлю его здесь.

Он упомянул кое-что о зависимом от аргумента поиске и предложил поместить операторы потока в пространство имен glm :: detail следующим образом:

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;
}

}} // glm::detail

После этого все работает нормально.

1 голос
/ 26 октября 2011

Вы опубликовали этот оператор извлечения:

template <class T>
std::istream& operator>>(std::istream& in, glm::detail::tvec2<T>& vec)

, но ошибка подразумевает, что он пытается скомпилировать это:

std::istream& std::operator>>(std::istream&&, _Tp&)
[with ... _Tp = glm::detail::tvec2<int>]

Вы уверены, что опубликованный вами код соответствует вашему?перекомпилировать?(Сфокусируйтесь на первом аргументе оператора, если вы не можете его сразу увидеть).


ОК, этот полный код прекрасно работает для меня:

#include <sstream>
#include <iostream>

#include <boost/lexical_cast.hpp>

template <class T>
struct tvec2 { 
    tvec2() : x(), y() {}
    tvec2(tvec2 const &) = default;
    tvec2(T x_, T y_) : x(x_), y(y_) {}

    T x;
    T y;
};

template <class T>
std::ostream& operator<<(std::ostream& out, const tvec2<T>& vec)
{
  out << vec.x << " " << vec.y;
  return out;
}

template <class T>
std::istream& operator>>(std::istream& in, tvec2<T>& vec)
{
    // yuck, boost disables skipws on the input stream
    in >> vec.x;
    if (in.good() && in.ignore(256, ' ').good())
        in >> vec.y;
    return in;
}

void test_operators()
{
    tvec2<int> intvec(2,3);
    std::cout << "intvec = {" << intvec << "}\n";

    std::stringstream ss;
    ss << intvec;

    tvec2<int> dupvec;
    ss >> dupvec;
    std::cout << "dupvec = {" << dupvec << "}\n";
}

void test_lexical_cast()
{
    std::cout << "and now with lexical_cast ...\n";
    tvec2<int> dupvec = boost::lexical_cast<tvec2<int> >("2 3");
    std::cout << "dupvec = {" << dupvec << "}\n";
}

int main()
{
    test_operators();
    test_lexical_cast();
}
...