namespace not needed

  • Thread starter Thread starter Manne Baum via .NET 247
  • Start date Start date
M

Manne Baum via .NET 247

namespace MyNS {
struct A {
int m;
};

template<typename T> T plus (const T& lhs, const T& rhs) { T ret(lhs); ret.m += rhs.m; return ret; } ///< + rhs
}

//==============================================================================
// M A I N
//------------------------------------------------------------------------------
void main()
{
MyNS::A a, b;
plus(a, b); //why not 'MyNS::' needed ???
}
 
Manne said:
namespace MyNS {
struct A {
int m;
};

template<typename T> T plus (const T& lhs, const T& rhs) { T
ret(lhs); ret.m += rhs.m; return ret; } ///< + rhs }

//==========================================================================
====
// M A I N
//--------------------------------------------------------------------------
----
void main()
{
MyNS::A a, b;
plus(a, b); //why not 'MyNS::' needed ???
}

It's called "argument dependent lookup". Because a and b are instances of a
class in namespace MyNS, the compiler searches MyNS (in addition to the
global namespace) for the definition of plus().

-cd
 
namespace MyNS {
struct A {
int m;
};

template<typename T> T plus (const T& lhs, const T& rhs) { T ret(lhs); ret.m += rhs.m; return ret; } ///< + rhs
}

//==============================================================================
// M A I N
//------------------------------------------------------------------------------
void main()
{
MyNS::A a, b;
plus(a, b); //why not 'MyNS::' needed ???
}

When you call an unqualified function (no namespace:: at the start),
the name is searched for first of all in the scope that the call is in
(in this case both "main" and the global scope), and also in any
namespaces that the parameters reside in (A is from MyNS, so MyNS is
also searched). This is called argument dependent lookup. I think MSVC
didn't properly support it until VC7.0.

Tom
 
tom_usenet said:
This is called argument dependent lookup. I think MSVC
didn't properly support it until VC7.0.

I think it was 7.1 actually. It absolutely was not supported in VC6 and
before.

-cd
 
I think it was 7.1 actually. It absolutely was not supported in VC6 and
before.

Except, slightly bizarrely, for operator overloads. e.g.

namespace ns
{
struct A{};
bool operator==(A a, A b)
{
return true;
}
}

int main()
{
ns::A a1, a2;
a1 == a2;
return 0;
}

compiles fine on MSVC6.

Tom
 
tom_usenet said:
Except, slightly bizarrely, for operator overloads. e.g.

I don't think that's bizarre. If you are going to implement argument
dependent lookup, the first place to do it is when resolving overloaded
operators, since that is the one place where adding a qualifier to the
function name isn't really possible. When I was working on a C++
compiler many years ago, that's exactly how I did it.
 
I don't think that's bizarre. If you are going to implement argument
dependent lookup, the first place to do it is when resolving overloaded
operators, since that is the one place where adding a qualifier to the
function name isn't really possible. When I was working on a C++
compiler many years ago, that's exactly how I did it.

I agree that that was the rationale, but I still find it "slightly
bizarre"; if you implement the ADL code for operators, and the
standard says it should work for other functions too, why wouldn't you
just reuse the ADL code for functions too?

My only idea is that ADL for non-operator functions was a fairly late
change to the standard. Certainly Andrew Koenig's original ADL
proposal only mentions operators:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0645.pdf

Tom
 
Back
Top