2016-05-10 9 views
1

boost_program_optionsで取得した値をboost :: units quantityに解析したコードに問題があります。以前はうまく動作していましたが、新しい設定ではもう動作しませんでした。あいまいなエラーメッセージは、program_optionsによって使用されるようなboost :: lexical_castの問題を示唆しています。boost :: units :: quantityのboost :: lexical_castがもうコンパイルされない

最小限の例では、(ここで私は、すべてのプログラムオプションのものを処分した)

これは私の古い設定にエラーなしでコンパイル
#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、1.49を後押し)ですが、GCC 4.9に.2ブースト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), 
      ^

を取得しますstringstreamから数量を読み込むには、すべて正常に動作します。

ここで間違っていることを誰かに教えてもらえますか?

+0

'boost :: units :: quantity c;'のみを含む簡単な 'main()'もコンパイルできません。あなたはできる? –

+1

@JohnZwinck:はい、両方の設定で問題なくコンパイルするだけです。どのようなエラーメッセージが表示されますか? – fedro

+0

ああ、私は '-Wno-unused-local-typedef'でコンパイルして、Boostで使われていないtypedefに関するスパムを避けなければなりませんでした。 –

答えて

1

フリー・ファンクションのように、オーバーロードされた演算子は、引数依存ルックアップによって配置される関連するネームスペース内にある必要があります。

operator>>への引数は、それぞれの名前空間 stdboost::unitsにあるので、あなたは、どちらか stdboost::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>の独自のラッパーを作成し、そこでオペレーターにストリームを提供することを検討する必要があります。

+0

本当にありがとう、それは本当にトリックをした!私はそれが前にどのように働いたのだろうか。 gcc 4.7.2はそれよりも寛大でしたか?また、gcc 4.9.2であっても、lexical_castを使わず、 'std :: stringstream'から' quantity 'を読み込もうとすると、オーバーロードされた演算子の検索がうまくいきます... – fedro

+0

@fedro複雑です;それは私が言うことができる限り、ブーストバージョンの違いです(gcc 4.7.2は古くなっていますが、この種のものが正しいです)。違いは、Boost.LexicalCastはブースト1.53以来、関連付けられた名前空間内のストリーム演算子のみを考慮に入れていることです。これは引数依存のルックアップによってそれらが配置されることが保証されているため、より堅牢です。引数のない依存ルックアップはODR違反につながる可能性があります(http://en.cppreference.com/w/cpp/language/dependent_name#Lookup_rules) – ecatmur

関連する問題