Archived
This forum has been archived. Please start a new discussion on GitHub.
Ice::ObjectPrx operator<< is in wrong namespace for argument dependent lookup.
Hi,
I'm using clang on apple:
$ c++ --version
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix
I'm on OS X 10.8.2
I'm using Ice 3.5.0.
This .cpp file does not output the proxy correctly under clang.
#include <iostream>
using namespace std;
template<typename T>
void print(const T& t)
{
cout << t << endl;
}
#include <Ice/Ice.h>
int main()
{
Ice::CommunicatorPtr ic = Ice::initialize();
Ice::ObjectPrx prx = ic->stringToProxy("ProxyName:tcp -h hostname -p 1000");
print(prx);
return 0;
}
#if 0
namespace IceInternal {
ostream& operator <<(ostream& os, const Ice::ObjectPrx& px)
{
::operator << (os,px);
return os;
}
}
#endif
What happens is because there is no operator<< in the IceInternal namespace (it is in the global namespace), it converts the proxy to a bool and outputs "1" instead of the proxy string.
This code works with gcc 4.6, but not with clang. To get the code to work with clang, you can undo the #if 0 block. At that point, I inject an operator << into the IceInternal and argument dependent lookup starts working.
I'm using clang on apple:
$ c++ --version
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix
I'm on OS X 10.8.2
I'm using Ice 3.5.0.
This .cpp file does not output the proxy correctly under clang.
#include <iostream>
using namespace std;
template<typename T>
void print(const T& t)
{
cout << t << endl;
}
#include <Ice/Ice.h>
int main()
{
Ice::CommunicatorPtr ic = Ice::initialize();
Ice::ObjectPrx prx = ic->stringToProxy("ProxyName:tcp -h hostname -p 1000");
print(prx);
return 0;
}
#if 0
namespace IceInternal {
ostream& operator <<(ostream& os, const Ice::ObjectPrx& px)
{
::operator << (os,px);
return os;
}
}
#endif
What happens is because there is no operator<< in the IceInternal namespace (it is in the global namespace), it converts the proxy to a bool and outputs "1" instead of the proxy string.
This code works with gcc 4.6, but not with clang. To get the code to work with clang, you can undo the #if 0 block. At that point, I inject an operator << into the IceInternal and argument dependent lookup starts working.
0
Comments
-
Hi David,
How did you compile the program? i cannot reproduce the issue using OS X 10.8 and same Clang version as youair:~ jose$ clang++ -v Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) Target: x86_64-apple-darwin12.3.0 Thread model: posix air:~ jose$ cat test.cpp #include <iostream> using namespace std; template<typename T> void print(const T& t) { cout << t << endl; } #include <Ice/Ice.h> int main() { Ice::CommunicatorPtr ic = Ice::initialize(); Ice::ObjectPrx prx = ic->stringToProxy("ProxyName:tcp -h hostname -p 1000"); print(prx); return 0; } air:~ jose$ g++ test.cpp -I/Library/Developer/Ice-3.5.0/include/ -L/Library/Developer/Ice-3.5.0/lib -lIce -lIceUtil air:~ jose$ ./a.out ProxyName -t -e 1.1:tcp -h hostname -p 1000
0 -
Here is my compile. One noteable difference is that I'm using -std=c++11 and -stdlib=libc++.
dawilcox-MacBookPro1:we dawilcox$ c++ -o template template_main.cpp -I/usr/local/include -g -O0 -std=c++11 -stdlib=libc++ -lIce -lIceUtil
dawilcox-MacBookPro1:we dawilcox$ ./template
1
dawilcox-MacBookPro1:we dawilcox$ cat template_main.cpp
#include <iostream>
using namespace std;
template<typename T>
void print(const T& t)
{
cout << t << endl;
}
#include <Ice/Ice.h>
int main()
{
Ice::CommunicatorPtr ic = Ice::initialize();
Ice::ObjectPrx prx = ic->stringToProxy("ProxyName:tcp -h hostname -p 1000");
print(prx);
return 0;
}
#if 0
namespace IceInternal {
ostream& operator <<(ostream& os, const Ice::ObjectPrx& px)
{
::operator << (os,px);
return os;
}
}
#endif0 -
I was able to reproduce the issue, it works with Clang if you include Ice.h before the declaration of print. We will look into this in more detail, thanks for reporting the problem.0