【问题标题】:std:: qualifier needed when overloaded namespace function exists?存在重载命名空间函数时需要 std:: 限定符吗?
【发布时间】:2014-11-19 15:02:34
【问题描述】:

如果我有一些类似的代码:

using namespace std;

namespace myNamespace
{
    vector<float> sqrt( vector<float> v ) { return v; }

    void func()
    {
        vector<float> myVec = { 1, 2, 3, 4 };
        std::cout << sqrt( myVec )[0] << std::endl;
        float myFloat = 4.0f;
        std::cout << sqrt( myFloat ) << std::endl; // need to use std::sqrt()
    }
}

除非我将标记行更改为使用std::sqrt,否则它将无法编译。为什么?我知道如果我尝试在myNamespace 中重新定义sqrt(float),那么如果我想使用标准库版本,我就必须符合std:: 的条件。编译器似乎试图转换 myFloat,而不是仅仅使用另一个 (std) 命名空间中的函数。

我发现解决此问题的一种方法是在std 命名空间中定义sqrt(vector&lt;float&gt;),但这感觉不太对,对this question 的回答建议std 中的重载是非法的。那时可能不是要走的路……

如何重载sqrt(或任何其他标准库 cmath 函数),这样我就不必总是限定使用哪一个并让编译器根据传递的函数参数进行选择?

谢谢。

【问题讨论】:

  • std 命名空间中声明自己的函数肯定是错误的。您可以在全局命名空间中声明它,因为由于某种原因您已将std 转储到其中。或者,您可以将 using std::sqrt; 添加到您的命名空间,以及您的 sqrt。我只是正确地限定了这个名字。
  • 你也可以不使用 use using namespace somethingsomething 而总是使用 std:: 前缀,完全避免这样的废话。

标签: c++ c++11 name-lookup


【解决方案1】:

在 C++ 中,name lookup 不关心参数类型,只有 名称 很重要。当编译器查找名为 sqrt 的函数时,它总是会首先找到您的版本(因为查找从封闭的命名空间开始),然后停止。

您必须通过在您的命名空间中使用 using 指令将来自 std:: 的名称带入作用域来帮助编译器:

namespace myNamespace
{
  using std::sqrt
  ...
}

然后,将执行标准重载决议以区分您的 sqrtstd::sqrt,并选择要调用的正确 sqrt 函数。

为避免任何歧义,您应始终限定名称(std::sqrtmyNamespace::sqrt


注意事项:

  • 正如 Simple 所指出的,Argument Dependent Lookup (ADL) 使std::sqrt 在第一种情况下可用于名称查找(因为vectorstd:: 中),但它不会改变您遇到的问题面对。

  • std:: 中声明自己的sqrt 函数是一个非常糟糕的主意(标准禁止,模板特化除外)

【讨论】:

  • 有没有办法将所有 std:: 名称带入当前命名空间?类似于使用 std::*?
  • 它确实关心参数类型。在第一次调用sqrt 时,编译器将通过ADL 找到myNamespace::sqrtstd::sqrt(因为vectorstd 中)。它只选择myNamespace::sqrt,因为它是一个更好的匹配。
【解决方案2】:

您可以通过myNamespace 中的声明using std::sqrt;std::sqrt 带入您的命名空间:

namespace myNamespace
{
    vector<float> sqrt( vector<float> v ) { return v; }
    using std::sqrt;
    ...

然后编译器会在std::cout &lt;&lt; sqrt( myFloat )中选择合适的sqrt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2015-09-15
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多