Из документации boost::fusion
:
Операторы ввода-вывода перегружены в пространстве имен boost::fusion.
Это означает, что если вы хотите неявно интегрировать эти operator<<
, вам нужно будет внедрить пространство имен boost::fusion
в ваше текущее пространство имен (здесь ::
) или использовать их явно.
Подводя итог, добавлю:
using namespace boost::fusion;
Должно работать в вашем случае. Или для явного использования вам придется написать:
boost::fusion::operator<<(std::cout, e) << std::endl;
--- ИЗМЕНИТЬ ---
После небольшого чтения кода boost::fusion
кажется, что вы запутались из-за поиска Кенига boost::fusion::operators::operator<<
, который выбирается в случае, если ваш аргумент является реальным boost::fusion::sequence
.
Вот почему вам не нужно внедрять пространство имен boost::fusion
или явно вызывать boost::fusion::operator<<
для типов, определенных в пространстве имен boost::fusion
.
Некоторые пояснения:
Я не буду объяснять всю концепцию поиска Кенига (также известного как Поиск, зависящий от аргумента). - ADL) здесь, так как это не главное, но, по сути, в нем говорится, что в случае, если вы используете переменную, тип которой находится внутри пространства имен, поиск функции распространяется на пространство имен этого параметра.
В этом конкретном случае включение boost/fusion/sequence/io/out.hpp
определит boost::fusion::operator::operator<<
, которое затем будет внедрено в пространство имен boost::fusion
.
$ 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 is just a SFINAE trick to ensure
// the function will only be selected for
// actual boost::fusion::sequence
operator<<(std::ostream& os, Sequence const& seq)
{
return fusion::out(os, seq); // this will print out the sequence
}
}
using operators::operator<<; // here the operator<< is injected
// in boost::fusion
}}
Это означает, что вызовы, использующие operator<<
с параметрами, типы которых находятся в boost::fusion
пространстве имен, найдут правильную перегрузку.
Вызовы с использованием аргументов, тип которых не находится в этом пространстве имен, не смогут разрешить правильную перегрузку operator<<
(это случай в вашем примере).
Вы можете проверить это, определив свой тип в пространстве имен boost::fusion
.
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; // ADL will work here
Примечание: если вы хотите отладить такие проблемы с поиском имен, вам следует использовать gdb
. Таким образом, вы всегда будете знать, какая перегрузка была выбрана. В таком случае:
$ 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);
person
NewbiZ
schedule
27.11.2013