【问题标题】:c++ namespace resolution ("automatic using" based on arguments?)c++ 命名空间解析(基于参数的“自动使用”?)
【发布时间】:2013-06-11 11:35:36
【问题描述】:

当我从这个命名空间之外调用一个在命名空间中声明的函数时,我通常需要显式地在命名空间前加上前缀:

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)

【问题讨论】:

  • “Argumentdependent lookup”是搜索词。
  • 您应该尝试发布一个工作示例的原因之一是它表明您自己已经尝试过这样的示例,并且让上述代码执行您所说的操作的唯一方法是有一个“使用”语句或从 mymath 范围内的东西内部调用 vector_cross。我建议你努力寻找一个最小的复制品,这将揭示原因。
  • @GManNickG:谢谢,我会检查一下
  • @kfsone:我自己试过这样一个例子,我只是去掉了main() 函数以缩短问题——我把它放回去,这样人们就可以复制/粘贴代码。但是,我根本没有使用任何using 语句。
  • Herp on me:我无法重新创建在粘贴您的编辑后不起作用的版本。 ADL 是 :(

标签: c++ namespaces token-name-resolution


【解决方案1】:

Q1:“适当”存在争议,但基本上是的,它选择结合各种“关联”命名空间的函数,这适用于许多示例。

Q2:你让几十个人加入 WG21,并最终将“修复 ADL”提案中的一项投票付诸实践,到目前为止,这些尝试都失败了。

Q2,务实的回答:ADL 仅适用于非限定查找,因此您始终可以选择使用限定名称。 (前缀 :: std:: 等等......)。或者完全停止使用命名空间。除此之外,您还受制于“柯尼希不确定性原理”。

【讨论】:

    猜你喜欢
    • 2013-02-08
    • 2019-03-29
    • 2011-09-20
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2014-01-10
    相关资源
    最近更新 更多