Boost::variant の使用方法については、Boost 基本的な使い方のオンライン チュートリアル ( http://www.boost.org/doc/libs/1_34_0/doc/html/variant/tutorial.html ) を使用して学習しようとしています。コツをつかむために、チュートリアル(以下)からコードの一部を取得してみました...
#include "boost/variant.hpp"
#include <iostream>
#include <complex>
void times_two(boost::variant<int, std::string, std::complex<double> > & v) {
if (int* pi = boost::get<int>(&v))
*pi *= 2;
else if (std::string* pstr = boost::get<std::string>(&v))
*pstr += *pstr;
//No check for complex - will silently return when variant is complex (BAD).
}
int main() {
boost::variant<int, std::string, std::complex<double> > v;
v = "hello";
std::string& str = boost::get<std::string>(v);
str += " world! ";
//the std::string contained by v now is equal to "hello world! ". Again, we can demonstrate this by streaming v to standard output:
std::cout << v << std::endl;
times_two(v);
std::cout << v << std::endl;
std::complex<double> a(5.0, 6.0);
v = a;
times_two(v);
return 0;
}
^ 正常にコンパイルされ、"hello world! hello world! hello world!" が返されます。期待どおり、複合型を取得してから戻ります。
そしたら改造してみた…
しかし、独自の構造体「structy」をバリアント サンプル プログラムに追加するとすぐに、次のようになります。
#include "boost/variant.hpp"
#include <iostream>
#include <complex>
struct structy {
int a;
};
void times_two(
boost::variant<int, std::string, std::complex<double>, structy> & v) {
if (int* pi = boost::get<int>(&v))
*pi *= 2;
else if (std::string* pstr = boost::get<std::string>(&v))
*pstr += *pstr;
//No check for complex or structy - should silently returns.
}
int main() {
boost::variant<int, std::string, std::complex<double>, structy> v;
v = "hello";
std::string& str = boost::get<std::string>(v);
str += " world! ";
//As desired, the std::string contained by v now is equal to "hello world! ". Again, we can demonstrate this by streaming v to standard output:
std::cout << v << std::endl;
times_two(v);
std::cout << v << std::endl;
std::complex<double> a(5.0, 6.0);
v = a;
times_two(v);
return 0;
}
g++4.7 でコンパイルすると、大量のエラー メッセージが表示されました。意味がわかりませんが、参考までに載せておきます。
定義したデータ型で動作しないのはなぜですか? 独自のユーザー定義クラスでも boost::static_visitor を使用しようとすると、この同じ巨大なエラー メッセージが表示されることに注意してください。
大きなエラーメッセージは次のとおりです。
johnmichaelreed@Ubuntu1204LTS:~/Downloads/boost_1_54_0$ g++ ~/temp.cpp -o temp
In file included from /usr/local/include/boost/variant/variant.hpp:2416:0,
from /usr/local/include/boost/variant.hpp:17,
from /home/johnmichaelreed/temp.cpp:1:
/usr/local/include/boost/variant/detail/variant_io.hpp: In member function ‘void boost::detail::variant::printer<OStream>::operator()(const T&) const [with T = structy, OStream = std::basic_ostream<char>]’:
/usr/local/include/boost/variant/variant.hpp:1017:32: instantiated from ‘boost::detail::variant::invoke_visitor<Visitor>::result_type boost::detail::variant::invoke_visitor<Visitor>::internal_visit(T&, int) [with T = const structy, Visitor = boost::detail::variant::printer<std::basic_ostream<char> >, boost::detail::variant::invoke_visitor<Visitor>::result_type = void]’
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: instantiated from ‘typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::invoke_visitor<boost::detail::variant::printer<std::basic_ostream<char> > >, VoidPtrCV = const void*, T = structy, typename Visitor::result_type = void, mpl_::true_ = mpl_::bool_<true>]’
/usr/local/include/boost/variant/detail/visitation_impl.hpp:173:9: instantiated from ‘typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::detail::variant::invoke_visitor<boost::detail::variant::printer<std::basic_ostream<char> > >, VoidPtrCV = const void*, T = structy, NoBackupFlag = boost::variant<int, std::basic_string<char>, std::complex<double>, structy>::has_fallback_type_, typename Visitor::result_type = void]’
/usr/local/include/boost/variant/detail/visitation_impl.hpp:260:1: instantiated from ‘typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>, step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<4l>, int, boost::mpl::l_item<mpl_::long_<3l>, std::basic_string<char>, boost::mpl::l_item<mpl_::long_<2l>, std::complex<double>, boost::mpl::l_item<mpl_::long_<1l>, structy, boost::mpl::l_end> > > > >, boost::mpl::l_iter<boost::mpl::l_end> >, Visitor = boost::detail::variant::invoke_visitor<boost::detail::variant::printer<std::basic_ostream<char> > >, VoidPtrCV = const void*, NoBackupFlag = boost::variant<int, std::basic_string<char>, std::complex<double>, structy>::has_fallback_type_, typename Visitor::result_type = void, mpl_::false_ = mpl_::bool_<false>]’
/usr/local/include/boost/variant/variant.hpp:2326:13: instantiated from ‘static typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::detail::variant::invoke_visitor<boost::detail::variant::printer<std::basic_ostream<char> > >, VoidPtrCV = const void*, T0_ = int, T1 = std::basic_string<char>, T2 = std::complex<double>, T3 = structy, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_, typename Visitor::result_type = void]’
/usr/local/include/boost/variant/variant.hpp:2348:13: instantiated from ‘typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor(Visitor&) const [with Visitor = boost::detail::variant::invoke_visitor<boost::detail::variant::printer<std::basic_ostream<char> > >, T0_ = int, T1 = std::basic_string<char>, T2 = std::complex<double>, T3 = structy, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_, typename Visitor::result_type = void]’
/usr/local/include/boost/variant/variant.hpp:2370:52: instantiated from ‘typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::apply_visitor(Visitor&) const [with Visitor = boost::detail::variant::printer<std::basic_ostream<char> >, T0_ = int, T1 = std::basic_string<char>, T2 = std::complex<double>, T3 = structy, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_, typename Visitor::result_type = void]’
/usr/local/include/boost/variant/detail/variant_io.hpp:88:5: instantiated from ‘std::basic_ostream<E, T>& boost::operator<<(std::basic_ostream<E, T>&, const boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&) [with E = char, T = std::char_traits<char>, U0 = int, U1 = std::basic_string<char>, U2 = std::complex<double>, U3 = structy, U4 = boost::detail::variant::void_, U5 = boost::detail::variant::void_, U6 = boost::detail::variant::void_, U7 = boost::detail::variant::void_, U8 = boost::detail::variant::void_, U9 = boost::detail::variant::void_, U10 = boost::detail::variant::void_, U11 = boost::detail::variant::void_, U12 = boost::detail::variant::void_, U13 = boost::detail::variant::void_, U14 = boost::detail::variant::void_, U15 = boost::detail::variant::void_, U16 = boost::detail::variant::void_, U17 = boost::detail::variant::void_, U18 = boost::detail::variant::void_, U19 = boost::detail::variant::void_]’
/home/johnmichaelreed/temp.cpp:25:16: instantiated from here
/usr/local/include/boost/variant/detail/variant_io.hpp:64:9: error: no match for ‘operator<<’ in ‘((const boost::detail::variant::printer<std::basic_ostream<char> >*)this)->boost::detail::variant::printer<std::basic_ostream<char> >::out_ << operand’
/usr/local/include/boost/variant/detail/variant_io.hpp:64:9: note: candidates are:
/usr/include/c++/4.6/ostream:110:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:110:7: note: no known conversion for argument 1 from ‘const structy’ to ‘std::basic_ostream<char>::__ostream_type& (*)(std::basic_ostream<char>::__ostream_type&) {aka std::basic_ostream<char>& (*)(std::basic_ostream<char>&)}’
/usr/include/c++/4.6/ostream:119:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ios_type& (*)(std::basic_ostream<_CharT, _Traits>::__ios_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>, std::basic_ostream<_CharT, _Traits>::__ios_type = std::basic_ios<char>]
/usr/include/c++/4.6/ostream:119:7: note: no known conversion for argument 1 from ‘const structy’ to ‘std::basic_ostream<char>::__ios_type& (*)(std::basic_ostream<char>::__ios_type&) {aka std::basic_ios<char>& (*)(std::basic_ios<char>&)}’
/usr/include/c++/4.6/ostream:129:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:129:7: note: no known conversion for argument 1 from ‘const structy’ to ‘std::ios_base& (*)(std::ios_base&)’
/usr/include/c++/4.6/ostream:167:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:167:7: note: no known conversion for argument 1 from ‘const structy’ to ‘long int’
/usr/include/c++/4.6/ostream:171:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:171:7: note: no known conversion for argument 1 from ‘const structy’ to ‘long unsigned int’
/usr/include/c++/4.6/ostream:175:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:175:7: note: no known conversion for argument 1 from ‘const structy’ to ‘bool’
/usr/include/c++/4.6/bits/ostream.tcc:93:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.6/bits/ostream.tcc:93:5: note: no known conversion for argument 1 from ‘const structy’ to ‘short int’
/usr/include/c++/4.6/ostream:182:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:182:7: note: no known conversion for argument 1 from ‘const structy’ to ‘short unsigned int’
/usr/include/c++/4.6/bits/ostream.tcc:107:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.6/bits/ostream.tcc:107:5: note: no known conversion for argument 1 from ‘const structy’ to ‘int’
/usr/include/c++/4.6/ostream:193:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:193:7: note: no known conversion for argument 1 from ‘const structy’ to ‘unsigned int’
/usr/include/c++/4.6/ostream:202:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:202:7: note: no known conversion for argument 1 from ‘const structy’ to ‘long long int’
/usr/include/c++/4.6/ostream:206:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:206:7: note: no known conversion for argument 1 from ‘const structy’ to ‘long long unsigned int’
/usr/include/c++/4.6/ostream:211:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:211:7: note: no known conversion for argument 1 from ‘const structy’ to ‘double’
/usr/include/c++/4.6/ostream:215:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:215:7: note: no known conversion for argument 1 from ‘const structy’ to ‘float’
/usr/include/c++/4.6/ostream:223:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:223:7: note: no known conversion for argument 1 from ‘const structy’ to ‘long double’
/usr/include/c++/4.6/ostream:227:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/include/c++/4.6/ostream:227:7: note: no known conversion for argument 1 from ‘const structy’ to ‘const void*’
/usr/include/c++/4.6/bits/ostream.tcc:121:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__streambuf_type*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>]
/usr/include/c++/4.6/bits/ostream.tcc:121:5: note: no known conversion for argument 1 from ‘const structy’ to ‘std::basic_ostream<char>::__streambuf_type* {aka std::basic_streambuf<char>*}’
/usr/local/include/boost/blank.hpp:93:46: note: template<class E, class T> std::basic_ostream<_CharT, _Traits>& boost::operator<<(std::basic_ostream<_CharT, _Traits>&, const boost::blank&)
/usr/local/include/boost/variant/detail/variant_io.hpp:79:46: note: template<class E, class T, class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9, class U10, class U11, class U12, class U13, class U14, class U15, class U16, class U17, class U18, class U19> std::basic_ostream<E, T>& boost::operator<<(std::basic_ostream<E, T>&, const boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&)
/usr/include/c++/4.6/complex:521:5: note: template<class _Tp, class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::complex<_Tp>&)
/usr/include/c++/4.6/ostream:528:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const unsigned char*)
/usr/include/c++/4.6/ostream:523:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed char*)
/usr/include/c++/4.6/ostream:510:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const char*)
/usr/include/c++/4.6/bits/ostream.tcc:323:5: note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const char*)
/usr/include/c++/4.6/ostream:493:5: note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const _CharT*)
/usr/include/c++/4.6/ostream:473:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, unsigned char)
/usr/include/c++/4.6/ostream:468:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, signed char)
/usr/include/c++/4.6/ostream:462:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, char)
/usr/include/c++/4.6/ostream:456:5: note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, char)
/usr/include/c++/4.6/ostream:451:5: note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, _CharT)
/usr/include/c++/4.6/bits/basic_string.h:2693:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
johnmichaelreed@Ubuntu1204LTS:~/Downloads/boost_1_54_0$
このエラーはどういう意味ですか? 私の変更がコードを壊したのはなぜですか?