Using Visual Studio 2010 SP1:
#include <vector>
//namespace XXX {
struct Test
{
bool operator==(const Test& r) const { return true; }
};
//}
//typedef XXX::Test Test;
template <typename T> inline bool operator!=(const T& l,const T& r)
{ return !(l==r); }
int main()
{
std::vector<Test> vt;
std::vector<Test> vt2 = std::move(vt);
return 0;
}
If I compile the code above as is, it fails with this error:
1>C:\apps\MVS10\VC\include\vector(609): error C2593: 'operator !=' is ambiguous
1> C:\apps\MVS10\VC\include\xmemory(268): could be 'bool std::operator !=<_Ty,_Ty>(const std::allocator<_Ty> &,const std::allocator<_Ty> &) throw()'
1> with
1> [
1> _Ty=Test
1> ]
1> test.cpp(11): or 'bool operator !=<std::allocator<_Ty>>(const T &,const T &)' [found using argument-dependent lookup]
1> with
1> [
1> _Ty=Test,
1> T=std::allocator<Test>
1> ]
1> while trying to match the argument list '(std::allocator<_Ty>, std::allocator<_Ty>)'
1> with
1> [
1> _Ty=Test
1> ]
1> C:\apps\MVS10\VC\include\vector(606) : while compiling class template member function 'void std::vector<_Ty>::_Assign_rv(std::vector<_Ty> &&)'
1> with
1> [
1> _Ty=Test
1> ]
... where vector(609)
resolves to this line:
else if (get_allocator() != _Right.get_allocator())
OTOH, if I uncomment the namespace XXX
-related lines, it compiles without complaint.
I have to think this is a compiler bug but I'm looking for some independent verification.
EDIT: Just by way of explanation, I came across this situation when recompiling some old code with VS2010 for the first time. The global operator was some cruft from years past (now removed). I just couldn't understand why some code failed and others didn't. The code above is my distillation of the failed case (obviously, old code would not contain calls to std::move()
).
UPDATE: I logged a bug with MS and they responded that this has been fixed "in the next release of the compiler" - which I presume means Visual C++ 11. See: http://connect.microsoft.com/VisualStudio/feedback/details/731692/regression-involving-global-operator-and-std-vector
vt=f()
) on an older GCC did work, but obviously that is not precisely equivalent to a version that supports rvalue-refs. I only later distilled it down to std::move(). – Maddiemadding