1

If we have a function in the global namespace and an overload with different argument types in another namespace, it seems that C++Builder compiler doesn't find the function from the global namespace.

namespace A
{
    class a {
        friend void swap(a& first, a& second) { }
    };
}

class b {
    friend void swap(b& first, b& second) { }
};

namespace C
{
    class c {
        A::a dataA;
        b dataB;

        friend void swap(c& first, c& second)
        {
            swap(first.dataA, second.dataA); // no problem
            swap(first.dataB, second.dataB); // VC++12 compiles, C++Builder XE doesn't
        }

        friend void swap2(c& first, c& second) // no problem with a different name
        {
            swap(first.dataA, second.dataA);
            swap(first.dataB, second.dataB);
        }
    };
}

C++Builder gives the following errors:

E2357 Reference initialized with 'b', needs lvalue of type 'c'
E2342 Type mismatch in parameter 'first' (wanted 'c &', got 'b')

Visual C++ 2012 compiles this without errors.

I have understood that the function in global namespace should be found even when there exists a function with the same name and different argument types.

Have I missed something, or is this a bug in C++Builder?

Samuli Hynönen
  • 662
  • 1
  • 8
  • 24

2 Answers2

2

It looks like a compiler bug to me. In both cases, ADL should kick in. In the first case, it looks in namespace A, including names in namespace A that were only declared in class a, and finds A::swap. In the second case, it looks in the global namespace (since that is where b is defined), including names in the global namespace that were only declare in class b, and finds ::swap.

Of course, it starts with unqualified name lookup, which will only find C::swap in both cases. Apparently, C++Builder somehow marks ::swap as hidden in this case, and fails to consider it in ADL. In the case of ADL, however, both the global namespace and namespace A should be treated equally.

The full rules are in §3.4.2. It's pretty heavy going, but for simple cases like yours, the implications are clear.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • XE is several versions old. If this has not already been fixed in a later version, then it needs to be filed in QC so it can get fixed. – Remy Lebeau Jul 13 '13 at 08:45
  • @RemyLebeau I don't have access to any version of CodeBuilder, so I can't test. It's up to the compiler's user community to verify this with the latest version, and send in a bug report if the error is still there. – James Kanze Jul 13 '13 at 17:31
0

Members of local scope with same name as global always hide global one so Call it like,A::a::swap(first.dataA, second.dataA);.

Hitesh Vaghani
  • 1,342
  • 12
  • 31