From the documentation of boost::fusion :
I / O statements overloaded in boost :: fusion namespace
This means that if you need an implicit integration of these operator<< , you need to enter the boost::fusion namespace in the current namespace ( :: here) or use them explicitly.
To summarize, add:
using namespace boost::fusion;
Should work in your case. Or for explicit use, you will need to write:
boost::fusion::operator<<(std::cout, e) << std::endl;
--- EDIT ---
After a little reading of the boost::fusion code, it seems like you got confused by looking for Koenig boost::fusion::operators::operator<< , which is selected if your argument is real boost::fusion::sequence .
This is why you do not need to enter the boost::fusion namespace or explicitly call boost::fusion::operator<< for the types defined in the boost::fusion namespace.
Some explanations:
I will not explain the whole Koenig search concept (also known as Dependent Lookup - ADL) here since it is not, but basically, it claims that if you use a variable whose type is inside the namespace, then the function search extends to the space names of this parameter.
In this particular case, including boost/fusion/sequence/io/out.hpp , boost::fusion::operator::operator<< will be defined, which will then be entered into the boost::fusion namespace.
$ cat /usr/local/include/boost/fusion/sequence/io/out.hpp [...] namespace boost { namespace fusion { [...] namespace operators { template <typename Sequence> inline typename boost::enable_if< fusion::traits::is_sequence<Sequence> , std::ostream& >::type
This means that calls using operator<< with parameters whose types are in the boost::fusion namespace will find the necessary overload.
Calls using arguments whose type is not in this namespace will not be able to allow proper operator<< overloading (this is in your example).
You can verify this by specifying your type in the boost::fusion namespace.
namespace boost { namespace fusion { struct employee { std::string name; int age; }; }} BOOST_FUSION_ADAPT_STRUCT( boost::fusion::employee, (std::string, name) (int, age)) [...] boost::fusion::employee e; std::cout << e << std::endl;
Note: if you want to debug such name lookup problems, you must use gdb . This way you will always know which overload has been selected. In this case:
$ cat fusion.cpp #include <iostream> #include <cstdlib> #include <boost/fusion/container/vector.hpp> #include <boost/fusion/sequence/io.hpp> int main(int, char**) { boost::fusion::vector<int, char> foo(42, '?'); std::cout << foo << std::endl; return EXIT_SUCCESS; } $ gdb -q ./fusion Reading symbols for shared libraries ... done (gdb) b 10 Breakpoint 1 at 0x1000012f7: file fusion.cpp, line 10. (gdb) r Starting program: /Users/avallee/Projects/tmp/fusion Reading symbols for shared libraries ++............................. done Breakpoint 1, main (unnamed_arg=0x7fff5fbffb60, unnamed_arg=0x7fff5fbffb60) at fusion.cpp:10 10 std::cout << foo << std::endl; (gdb) s boost::fusion::operators::operator<< <boost::fusion::vector<int, char, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > ( os=@0x7fff762b5f10 , seq=@0x7fff5fbffb18 ) at out.hpp:38 38 return fusion::out(os, seq);