boost :: lexical_cast с boost :: units :: amount больше не компилируется

У меня есть проблема с кодом, который анализирует значения, полученные через boost_program_options, чтобы увеличить :: единицы измерения. Раньше он работал просто отлично, а теперь, на новой установке, больше не работает. Непонятное сообщение об ошибке намекает на проблему с boost :: lexical_cast, который, кажется, используется program_options.

Минимальный пример (в котором я избавился от всех опций программы)

#include <iostream>
#include <boost/units/io.hpp>
#include <boost/units/systems/si.hpp>
#include <boost/units/systems/si/io.hpp>
#include <boost/lexical_cast.hpp>
#include <sstream>

using namespace boost::units;

std::istream& operator>>(std::istream& in, quantity<si::current>& c)
{
c = quantity<si::current>(0.7 * si::ampere);
return in;
}

int main()
{
quantity<si::current> c = boost::lexical_cast<quantity<si::current> >("3.0A");
std::cout << c << std::endl;
}

Он компилируется без ошибок на моей старой установке (gcc 4.7.2, boost 1.49), но на gcc 4.9.2 с boost 1.55 больше не компилируется (кстати, пожалуйста, игнорируйте тот факт, что даже если он компилируется, он генерирует исключение в любом случае, потому что на самом деле ничего не читается из потока; я не хотел запутывать этот пост, включая всю логику синтаксического анализа). Вместо этого я получаю сообщение об ошибке

In file included from /usr/include/boost/serialization/tracking.hpp:20:0,
from /usr/include/boost/serialization/nvp.hpp:32,
from /usr/include/boost/units/io.hpp:27,
from bla3.cpp:2:
/usr/include/boost/lexical_cast.hpp: In instantiation of ‘struct boost::detail::deduce_target_char_impl<boost::detail::deduce_character_type_later<boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::current_base_dimension, boost::units::static_rational<1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > > > > > >’:
/usr/include/boost/lexical_cast.hpp:415:89:   required from ‘struct boost::detail::deduce_target_char<boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::current_base_dimension, boost::units::static_rational<1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > > > > >’
/usr/include/boost/lexical_cast.hpp:674:92:   required from ‘struct boost::detail::lexical_cast_stream_traits<const char*, boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::current_base_dimension, boost::units::static_rational<1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > > > > >’
/usr/include/boost/lexical_cast.hpp:2363:19:   required from ‘static Target boost::detail::lexical_cast_do_cast<Target, Source>::lexical_cast_impl(const Source&) [with Target = boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::current_base_dimension, boost::units::static_rational<1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > > > >; Source = const char*]’
/usr/include/boost/lexical_cast.hpp:2543:50:   required from ‘Target boost::lexical_cast(const Source&) [with Target = boost::units::quantity<boost::units::unit<boost::units::list<boost::units::dim<boost::units::current_base_dimension, boost::units::static_rational<1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > > > >; Source = char [5]]’
bla3.cpp:18:81:   required from here
/usr/include/boost/lexical_cast.hpp:388:13: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’
BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value),
^

Если в лексическом приведении я использую другой пользовательский тип (не boost :: units :: amount) и перегружаю его оператором >>, или если я непосредственно пытаюсь прочитать количество из потока строк, все работает нормально.

Может кто-нибудь сказать мне, что я здесь делаю не так?

1

Решение

Перегруженный оператор, как и свободная функция, должен находиться в связанном пространстве имен, чтобы найти его в зависимости от аргументов.

В этом случае вам нужно будет открыть std или же boost::units пространства имен, так как аргументы operator>> находятся в пространстве имен std а также boost::units соответственно:

namespace boost { namespace units {

std::istream& operator>>(std::istream& in, quantity<si::current>& c)
{
c = quantity<si::current>(0.7 * si::ampere);
return in;
}

}}

Это должно указывать вам на то, что это не совсем безопасно, поскольку ваш код будет конфликтовать с любым потоком в операторе, предоставленном Boost.Units в будущей версии, или другим сторонним пользователем. Вы должны рассмотреть возможность написания своей собственной обертки для quantity<si::current> и подача потока в оператор там.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector