Discussion:
[format] compilation error
Johan Råde
2009-09-18 09:17:46 UTC
Permalink
Hi,

I'm using Boost 1.38 and Visual Studio 2008.
The following code

#include <boost/format.hpp>
#include <ostream>
#include <vector>

using boost::format;
using std::ostream;
using std::vector;

ostream& operator<<(ostream& os, const vector<int>& v)
{
os << '[';
for(size_t i = 0; i < v.size(); ++i) {
if(i > 0) os << ' ';
os << v[i];
}
os << ']';
return os;
}

void f()
{
vector<int> v;
str(format("%1%") % v);

}

fails to compile with the error message

1>c:\libraries\boost\boost_1_38_0\boost\format\feed_args.hpp(100) : error C2679: binary '<<' : no
operator found which takes a right-hand operand of type 'const std::vector<_Ty>' (or there is no
acceptable conversion)
1> with
1> [
1> _Ty=int
1> ]

Why? How do I fix this?

Thank you,
Johan Råde
Ronny Spiegel
2009-09-18 09:59:31 UTC
Permalink
Hi Johan,
Post by Johan RÃ¥de
ostream& operator<<(ostream& os, const vector<int>& v)
{
...
this operator should be defined in the std namespace (ADL) - the problem
is that you're not allowed to do this.

Unfortunately I do not have a solution to this problem at the moment :(

Regards,

RSp
Anthony Foglia
2009-09-18 15:06:27 UTC
Permalink
Post by Johan RÃ¥de
I'm using Boost 1.38 and Visual Studio 2008.
The following code
[includes and usings omitted]
Post by Johan RÃ¥de
ostream& operator<<(ostream& os, const vector<int>& v)
{
[function body omitted]
Post by Johan RÃ¥de
}
void f()
{
vector<int> v;
str(format("%1%") % v);
}
fails to compile with the error message
error C2679: binary '<<' : no operator found which takes a right-hand
operand of type 'const std::vector<_Ty>' (or there is no acceptable
conversion)
1> with
1> [
1> _Ty=int
1> ]
Why? How do I fix this?
The problem is that in feed_args.hpp when operator<< is called, the
compiler looks in the namespaces boost and std. The former because
that's the current namespace, and std because that's the namespace of
the vector argument. It finds some candidates, none of which work for
vector<int> and throws the error. It never bothers to check the global
namespace.

I don't know if there's a recommended solution for this, but you can
try specializing the operator<< in std namespace

namespace std {
template<>
ostream & operator<<(ostream & os, const vector<int>& v)
{
// Your code here
}
}

I believe that is allowed because you are fully specializing the
template. You aren't allowed to overload for a general vector<T> though.

For a better explanation, check out this old GotW:
http://www.gotw.ca/publications/mill08.htm
--
Anthony Foglia
Princeton Consultants
(609) 987-8787 x233
Loading...