With this sample program I observe a different behavior in g++ and clang
Foo.h:
#include <iostream>
namespace Bar
{
class Foo
{
public:
Foo(int x) : _x(x)
{}
int x() const
{
return _x;
}
private:
int _x;
};
}
std::ostream& operator <<(std::ostream& os, const Bar::Foo* foo);
Foo.cpp
#include <Foo.h>
using namespace std;
ostream& operator <<(ostream& os, const Bar::Foo* foo)
{
return os << foo->x();
}
main.cpp
#include <iostream>
using namespace std;
template<typename T>
void print(const T& t)
{
cout << t << endl;
}
#include <Foo.h>
int main(int argc, char** argv)
{
Bar::Foo* foo = new Bar::Foo(5);
print(foo);
}
Compiling with clang++ and g++ produce different results:
air:~ jose$ clang++ Foo.cpp main.cpp -I.
air:~ jose$ ./a.out
0x7ff9e84000e0
air:~ jose$ g++ Foo.cpp main.cpp -I.
air:~ jose$ ./a.out
5
Which one is correct and why?.
#includes to a single pasteable entity.operator<<takes aBar::Foo const *, but through theprint()template your sending aBar::Foo * const(the reference is immaterial at that point). Take out the template and just send the pointer-direct tocoutand see what both toolchains give you. The better be the same.operator<<inside the namespaceBar, so that Argument Dependent Lookup will find it.Barnamespace, this is not the root cause of the issue. The call occurs in the global namespace, so name lookup should find the OP's overload and prefer it over the one accepting avoid const*.