我正在尝试通过使用 Boost 基本用法在线教程( http://www.boost.org/doc/libs/1_34_0/doc/html/variant/tutorial.html)来学习如何使用 Boost::variant 。为了掌握它,我尝试从教程(下)中获取一些代码......
#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$
这个错误是什么意思?为什么我的修改会破坏代码?