[fusion] adapted std::pair and ostream
Hi The docs: http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/adapted/std... seem to suggest that one can pipe an adapted std::pair 'directly' to cout. I find the following though: #include <iostream> #include <boost/fusion/adapted.hpp> // adapt pair. #include <boost/fusion/sequence.hpp> // operator<<() ? #include <boost/fusion/container.hpp> // as_vector int main(int argc, char** argv) { std::pair<std::string, int> p("foo", 7); std::cout << p << std::endl; // does not compile although docs suggest it should. std::cout << boost::fusion::as_vector(p) << std::endl; // compiles and works as expected. return 0; } Am I missing an include? Is sending to cout without first using as_vector actually supported? Daniel
The docs:
http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/adapted/std...
seem to suggest that one can pipe an adapted std::pair 'directly' to cout.
I find the following though:
#include <iostream> #include <boost/fusion/adapted.hpp> // adapt pair. #include <boost/fusion/sequence.hpp> // operator<<() ? #include <boost/fusion/container.hpp> // as_vector
int main(int argc, char** argv) { std::pair<std::string, int> p("foo", 7);
std::cout << p << std::endl; // does not compile although docs suggest it should. std::cout << boost::fusion::as_vector(p) << std::endl; // compiles and works as expected.
return 0; }
Am I missing an include? Is sending to cout without first using as_vector actually supported?
Hmm... well boost/fusion/sequence/io/out.hpp (which is included by boost/fusion/sequence/io.hpp which is in turn included by boost/fusion/sequence.hpp) does define the correct operator<< for all sequences, but it's in the boost::fusion namespace, and I don't see it being exported into the global namespace anywhere. If you add "using boost::fusion::operator<<;" to your code, it works fine. But this seems to be in contradiction with the docs, which say [1] (emphasis mine): The **global** operator<< has been overloaded for generic output streams such that Sequence(s) are output by recursively calling operator<< for each element. Perhaps the authors were relying on ADL to find operator<<, but overlooking the fact that not all sequences would be in the boost::fusion namespace? Regards, Nate.
On 7/20/2011 3:40 AM, Nathan Ridge wrote:
The docs:
http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/adapted/std...
seem to suggest that one can pipe an adapted std::pair 'directly' to cout.
I find the following though:
#include <iostream> #include <boost/fusion/adapted.hpp> // adapt pair. #include <boost/fusion/sequence.hpp> // operator<<() ? #include <boost/fusion/container.hpp> // as_vector
int main(int argc, char** argv) { std::pair<std::string, int> p("foo", 7);
std::cout << p << std::endl; // does not compile although docs suggest it should. std::cout << boost::fusion::as_vector(p) << std::endl; // compiles and works as expected.
return 0; }
Am I missing an include? Is sending to cout without first using as_vector actually supported?
Hmm... well boost/fusion/sequence/io/out.hpp (which is included by boost/fusion/sequence/io.hpp which is in turn included by boost/fusion/sequence.hpp) does define the correct operator<< for all sequences, but it's in the boost::fusion namespace, and I don't see it being exported into the global namespace anywhere.
If you add "using boost::fusion::operator<<;" to your code, it works fine.
But this seems to be in contradiction with the docs, which say [1] (emphasis mine):
The **global** |operator<<| has been overloaded for generic output streams such that Sequence <http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/sequence.html>(s) are output by recursively calling |operator<<| for each element.
Perhaps the authors were relying on ADL to find operator<<, but overlooking the fact that not all sequences would be in the boost::fusion namespace?
Thanks. That's certainly not correct. Adapted sequences in other namespaces can't avail of that. I just fixed the docs to avoid further confusion. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
But this seems to be in contradiction with the docs, which say [1] (emphasis mine):
The **global** |operator<<| has been overloaded for generic output streams such that Sequence <http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/sequence.html>(s) are output by recursively calling |operator<<| for each element.
Perhaps the authors were relying on ADL to find operator<<, but overlooking the fact that not all sequences would be in the boost::fusion namespace?
Thanks. That's certainly not correct. Adapted sequences in other namespaces can't avail of that. I just fixed the docs to avoid further confusion.
Why not just overload operators << and >> in the global namespace, as the docs say, rather than overloading them in the boost::fusion namespace? Regards, Nate.
On 7/20/2011 7:21 AM, Nathan Ridge wrote:
But this seems to be in contradiction with the docs, which say [1] (emphasis mine):
The **global** |operator<<| has been overloaded for generic output streams such that Sequence <http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/sequence.html>(s) are output by recursively calling |operator<<| for each element.
Perhaps the authors were relying on ADL to find operator<<, but overlooking the fact that not all sequences would be in the boost::fusion namespace?
Thanks. That's certainly not correct. Adapted sequences in other namespaces can't avail of that. I just fixed the docs to avoid further confusion.
Why not just overload operators << and >> in the global namespace, as the docs say, rather than overloading them in the boost::fusion namespace?
I didn't want to pollute the global namespace. At one point, I only had native fusion sequences. However, in light of recent events, where more foreign sequences have been adapted, and some of those with namespaces that cannot be touched (e.g. std), this is indeed seems necessary. I'll take that into consideration. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
Why not just overload operators << and >> in the global namespace, as the docs say, rather than overloading them in the boost::fusion namespace?
I didn't want to pollute the global namespace. At one point, I only had native fusion sequences. However, in light of recent events, where more foreign sequences have been adapted, and some of those with namespaces that cannot be touched (e.g. std), this is indeed seems necessary. I'll take that into consideration.
Well, since the operator is guarded by an enable_if<fusion::traits::is_sequence<T>>, I would say it doesn't pollute the global namespace any more than we desire it to. Regards, Nate.
On 7/20/2011 7:49 AM, Nathan Ridge wrote:
Why not just overload operators << and >> in the global namespace, as the docs say, rather than overloading them in the boost::fusion namespace?
I didn't want to pollute the global namespace. At one point, I only had native fusion sequences. However, in light of recent events, where more foreign sequences have been adapted, and some of those with namespaces that cannot be touched (e.g. std), this is indeed seems necessary. I'll take that into consideration.
Well, since the operator is guarded by an
enable_if<fusion::traits::is_sequence<T>>,
I would say it doesn't pollute the global namespace any more than we desire it to.
Agreed. The situation is different now than it was 8-10 years ago. What you see is historical. Heh, we might not even had enable_if before, and definitely no user crafted and adapted views and sequences. What you see is almost a port from boost.tuple, including the copyrights from the authors! :-) Time flies! Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
On 7/19/2011 6:28 PM, Daniel James wrote:
Hi
The docs:
http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/adapted/std...
seem to suggest that one can pipe an adapted std::pair 'directly' to cout.
I find the following though:
#include <iostream> #include <boost/fusion/adapted.hpp> // adapt pair. #include <boost/fusion/sequence.hpp> // operator<<() ? #include <boost/fusion/container.hpp> // as_vector
int main(int argc, char** argv) { std::pair<std::string, int> p("foo", 7);
std::cout << p << std::endl; // does not compile although docs suggest it should. std::cout << boost::fusion::as_vector(p) << std::endl; // compiles and works as expected.
return 0; }
Am I missing an include? Is sending to cout without first using as_vector actually supported?
No, it can't compile. It will only compile if ADL pickus up the << from boost::fusion, but it can't do that because pair is in namespace std. Could you point me to the docs where it says it should? It's probably a doc bug. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
No, it can't compile. It will only compile if ADL pickus up the << from boost::fusion, but it can't do that because pair is in namespace std. Could you point me to the docs where it says it should? It's probably a doc bug.
From [1]:
"The I/O operators: << and >> work generically on all Fusion sequences. The global operator<< has been overloaded for generic output streams such that Sequence(s) are output by recursively calling operator<< for each element. Analogously, the global operator>> has been overloaded to extract Sequence(s) from generic input streams by recursively calling operator>> for each element." Notice it says the **global** operators << and >> are overloaded. Regards, Nate. [1] http://www.boost.org/doc/libs/1_47_0/libs/fusion/doc/html/fusion/sequence/op...
participants (3)
-
Daniel James
-
Joel de Guzman
-
Nathan Ridge