c++ - boost::lexical_cast with boost::units::quantity 不再编译

标签 c++ gcc lexical-cast boost-units

我在解析通过 boost_program_options 获取的值到 boost::units 数量的代码时遇到问题。它曾经工作得很好,现在,在一个新的设置上,不再工作了。模糊的错误消息暗示了 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)上编译没有错误,但是在带有 boost 1.55 的 gcc 4.9.2 上不再编译(顺便说一句,请忽略即使它编译,它抛出的事实在任何一种情况下都是异常,因为实际上没有从流中读取任何内容;我不想通过包含整个解析逻辑来混淆这篇文章)。相反,我收到了错误消息

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::quantity)并为其重载 >> 运算符,或者如果我直接尝试从 stringstream 中读取数量,一切正常.

谁能告诉我我做错了什么?

最佳答案

重载运算符,如自由函数,需要位于关联的命名空间中才能通过参数相关查找找到。

在这种情况下,您需要打开 stdboost::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;
}

}}

这应该向您表明这并不完全安全,因为您的代码会与 future 版本中由 Boost.Units 或其他第 3 方用户提供的运算符中的任何流发生冲突。您应该考虑为 quantity<si::current> 编写自己的包装器并在那里的运算符(operator)中提供一个流。

关于c++ - boost::lexical_cast with boost::units::quantity 不再编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37135275/

相关文章:

c++ - boost lexical_cast <int> 检查

c++ - boost::lexical_cast 从字符串到字符异常

c++ - 创建整数二维数组(与字符串二维数组相比)而不提及维度

c++ - 如何使用常规 makefile 构建依赖于 boost 的项目?

c++ - C++11 是否强制 pow(double, int) 使用较慢的 pow(double, double)?

c++ - 如何在 C++ 程序中查看 gdb 中的 vtable?

c++ - Stringstream 到 vector<int>

c++ - 在不关注程序窗口的情况下捕获键盘输入

c++ - 可嵌入的文档存储数据库

c - glibc链接差异导致段错误