4

When I call a function declared in a namespace from outside this namespace, I usually need to explicitly prefix with the namespace:

namespace ns1 {
    void myfunc();
}

myfunc();        // compiler complains
ns1::myfunc();   // good

However I have this situation where it seems the compiler can automatically devise what function I want to use:

namespace mymath {
    struct Vector3 {
        float x, y, z;
    };
    Vector3 vector_cross(const Vector3& lhs, const Vector3 &rhs)
    {
        return lhs; // Pretend this is a cross product
    }
} // ns

int main(int argc, char** argv)
{
    mymath::Vector3 v, w, x;
    x = vector_cross(v, w);   // <---- Here, I do not need to
                              //       prefix with the namespace
    return 0;
}

Q1: Is it because the compiler can automatically select the appropriate function based on the arguments type? Or something else?


After more testing, I found out that my compiler does not complain if I add another function with the same declaration in another namespace:

namespace mymath {
    // same as above
} // ns

namespace math2 {
    mymath::Vector3 vector_cross(const mymath::Vector3& lhs, const mymath::Vector3 &rhs)
    {
        return rhs; // Return rhs this time
    }
} // ns

int main(int argc, char** argv)
{
    mymath::Vector3 v, w, x;
    x = vector_cross(v, w);   // <---- Here, which one did the compiler chose?
    return 0;
}

Q2: How can I de-activate this behavior?

Edit: My compiler: gcc version 4.7.2 (Debian 4.7.2-5)

Julien-L
  • 5,267
  • 3
  • 34
  • 51
  • 7
    "Argument dependent lookup" is the search term. – GManNickG Jun 14 '13 at 18:29
  • One of the reasons you should try to post a working example is that it shows that you have tried such an example yourself, and the only way to get the above code to do what you say it does is to have a "using" statement or to be calling vector_cross from inside something that is scoped within mymath. I suggest you work to find a minimal repro and that will reveal the cause. – kfsone Jun 14 '13 at 18:30
  • @kfsone: I have tried such an example myself, I just stripped the `main()` function away to make the question shorter--I put it back so one can copy/paste the code. However, I have not used any `using` statement at all. – Julien-L Jun 14 '13 at 18:37
  • Herp on me: I can't recreate the version that didn't work after I pasted in your edit. ADL it is :( – kfsone Jun 14 '13 at 19:35

1 Answers1

5

Q1: 'appropriate' is debated, but essentially yes, it selects function combining all kinds of "associated" namespaces, that works fine for many samples.

Q2: You make a few dozen people join WG21 and finally vote one of the 'fix ADL' proposals to life, this far the attempts fell flat.

Q2, pragmatic answer: ADL only applies to unqualified lookup, so you always have the option to use qualified names. (prefix :: std:: and so on...). Or stop using namespaces completely. Other than that you are subject to "Koenig uncertainty principle".

Balog Pal
  • 16,195
  • 2
  • 23
  • 37