Von der boost::fusion
Dokumentation:
Die I/O-Operatoren im Namensraum boost überlastet sind :: Fusion
Was bedeutet, dass, wenn Sie eine implizite Integration dieser operator<<
wollen, Sie müssen den Namespace boost::fusion
in Ihren aktuellen Namespace (::
hier) injizieren oder sie explizit verwenden.
Um es allen zu, und fügte hinzu:
using namespace boost::fusion;
Sollte in Ihrem Fall arbeiten. Oder für eine explizite Verwendung, müssen Sie schreiben:
boost::fusion::operator<<(std::cout, e) << std::endl;
--- EDIT ---
Nach boost::fusion
‚s-Code ein bisschen lesen, scheint es, dass Sie wegen unklarer sind die Koenigs Suche von boost::fusion::operators::operator<<
die ausgewählt wird, falls Ihr Argument eine echte boost::fusion::sequence
ist. Dies ist
, warum Sie nicht die boost::fusion
Namespace injizieren müssen, noch explizit boost::fusion::operator<<
für Typen im boost::fusion
Namespace definiert nennen.
Einige Erklärungen:
Ich werde das gesamte Konzept der Koenig-Lookup (auch als Argument Dependent Lookup bekannt - ADL) nicht erklären hier, da dies nicht der Punkt ist, aber im Grunde heißt es, dass Sie ein in Fall verwenden Variable, deren Typ sich in einem Namespace befindet, dann erstreckt sich die Funktionssuche auf den Namespace dieses Parameters.
In diesem speziellen Fall definiert boost/fusion/sequence/io/out.hpp
boost::fusion::operator::operator<<
, die dann in den Namespace boost::fusion
injiziert werden.
$ 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
}}
Das bedeutet, dassoperator<<
mit Parametern, deren Typen sind in derboost::fusion
Namespace ruft die richtige Überlastung finden.
Aufrufe, die Argumente verwenden, deren Typ sich nicht in diesem Namespace befindet, lösen die richtige Überladung von operator<<
nicht (das ist in Ihrem Beispiel der Fall).
Sie können dies überprüfen, indem Sie Ihren Typ im Namespace boost::fusion
definieren.
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
Randbemerkung: Wenn Sie diese Art von Namenssuche Probleme debuggen wollen, sollten Sie gdb
verwenden. So wissen Sie immer, welche Überladung gewählt wurde. In diesem Fall:
$ 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_> > ([email protected], [email protected]) at out.hpp:38
38 return fusion::out(os, seq);