来自 boost::fusion
文档:
输入输出操作符在命名空间 boost::fusion 中被重载。
这意味着,如果您想要隐式地使用这些 operator<<
,您需要将命名空间 boost::fusion
注入到当前的命名空间中(在这里是 ::
),或者显式地使用它们。
总之,添加以下代码:
using namespace boost::fusion
应该可以在你的情况下工作。
或者为了明确使用,你将不得不编写:
boost::fusion::operator<<(std::cout, e) << std::endl;
--- 编辑 ---
经过一些阅读 boost::fusion
的代码,似乎你对于 Koenig's lookup 和 boost::fusion::operators::operator<<
的使用会感到困惑。在参数为一个真正的 boost::fusion::sequence
时,就会选择这种方法。
这就是为什么你不需要引入 boost::fusion
命名空间,也不需要显式地调用 boost::fusion::operator<<
来处理在 boost::fusion
命名空间中定义的类型。
一些解释:
我不会在这里解释整个 Koenig lookup 概念(也称为 Argument Dependent Lookup - 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
operator<<(std::ostream& os, Sequence const& seq)
{
return fusion::out(os, seq);
}
}
using operators::operator<<;
}}
这意味着使用 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;
顺便提一下:如果你想调试这种名称查找问题,你应该使用 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);