Re: VC8 compiler behavior?
Hi,
Sam Stump wrote:
The code below does not compile with VC8. The error is:
sample.cpp(36) : error C2679: binary '<<' : no operator found which takes
a right-hand operand of type 'const std::vector<_Ty>' (or there is no
acceptable conversion)
with
[
_Ty=int
]
but it is clearly there. Is this conformant behavior or a bug?
================= begin code =====================
// sample.cpp
#include <vector>
#include <iostream>
// move the operator below inside the namespace, then it will compile ...
template <class T>
std::ostream& operator<<(std::ostream& ostr, const std::vector<T>& v)
{
// output comma delimited vector elements ...
std::vector<T>::const_iterator end = v.end();
for (std::vector<T>::const_iterator it = v.begin(); it != end; ++it) {
ostr << *it;
if (it + 1 != end) ostr << ", ";
}
return ostr;
}
namespace formatter {
template <class T>
class bracketed {
public:
bracketed(const T& t) : value(t) {}
const T& value;
private:
// not implemented ...
bracketed<T>& operator=(const bracketed<T>&);
};
template <class T>
std::ostream& operator<<(std::ostream& ostr, const bracketed<T>& v)
{
// enclose value in brackets ...
return ostr << '[' << v.value << ']';
}
};
int main()
{
using formatter::bracketed;
// easy example ...
int x = 21014;
std::cout << bracketed<int>(x) << std::endl;
// more complicated example ...
std::vector<int> v;
v.push_back(2);
v.push_back(1);
v.push_back(0);
v.push_back(1);
v.push_back(4);
std::cout << bracketed<std::vector<int> >(v) << std::endl;
}
The following simplified code emulates the problem:
// >>>>>>>>> begin
namespace M
{
class A {};
class B {};
void f(A, int);
}
void f(M::A, M::B);
namespace N
{
struct D
{
M::B b;
};
void f(M::A a, D d)
{
f(a, d.b);
// should look in current namespace, in namespace M
// where A is declared and in global namespace (but does not)
// error message in VC8:
// error C2665: 'N::f' : none of the 2 overloads could convert all
the argument types
// could be 'void M::f(M::A,int)' [found using argument-dependent
lookup]
// or 'void N::f(M::A,N::D)'
}
}
int main()
{
f(M::A(), N::D());
return (0);
}
// <<<<<<<<< end
It look really strange to me (looks mor like a bug) that the name
lookup
algorithm does not find the matching global function
(3.4.2 Argument-dependent name lookup [basic.lookup.koenig])
"...the set of declarations found by the lookup of the function name
is the union of the set of declarations found using ordinary
unqualified
lookup and the set of declarations found in the namespaces and classes
associated with the argument types."
(BTW: the same problem is present while compiling with gcc 3.2.2)
Cheers!
--
Hrayr
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]