C++ 命名空间解析("automatic using"基于参数?

c++ namespace resolution ("automatic using" based on arguments?)

本文关键字:于参数 参数 automatic 命名空间 C++ using      更新时间:2023-10-16

从名称空间外部调用在名称空间中声明的函数时,通常需要显式地使用名称空间前缀:

namespace ns1 {
    void myfunc();
}
myfunc();        // compiler complains
ns1::myfunc();   // good

然而,我有这种情况,似乎编译器可以自动设计我想使用的函数:

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:这是因为编译器可以根据参数类型自动选择合适的函数吗?还是别的什么?


经过更多的测试,我发现如果我在另一个命名空间中添加另一个具有相同声明的函数,编译器不会报错:

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:如何停用此行为?

编辑:

编译器:gcc version 4.7.2 (Debian 4.7.2-5)

Q1: '适当'是有争议的,但本质上是的,它选择了结合各种"相关"名称空间的函数,这对于许多示例都很好。

Q2:你让几十个人加入WG21,并最终投票支持"修复ADL"的提案之一,到目前为止,这些尝试都失败了。

Q2,实用的答案:ADL仅适用于非限定查找,因此您始终可以选择使用限定名称。(前缀::std::等等…)。或者完全停止使用名称空间。除此之外,你必须遵守"柯尼格测不准原理"