【问题标题】:Does declaring swap() in namespace foo and then using swap() instead of foo::swap() under the same namespace imply foo::swap()?在命名空间 foo 中声明 swap(),然后在同一命名空间下使用 swap() 而不是 foo::swap() 是否意味着 foo::swap()?
【发布时间】:2016-01-04 19:54:06
【问题描述】:

我的问题很简单。执行以下操作是否安全?

不需要任何道德建议,例如“不要将函数命名为 swap()!”或者别的什么,拜托!

file1.hpp

//header guards here
#include <utility>  //includes std::swap and std::move

namespace foo 
{
    template<typename T>
    inline void swap(T& lhs, T& rhs)
    {
        T temp = std::move(lhs);
        lhs = std::move(rhs);
        rhs = std::move(temp);
    }
}

file2.cpp

#include "file1.hpp"

namespace foo
{
    template<typename T>
    void myfun(T a, T b) 
    { 
        a += b; 
        swap(a, b);  //does it imply foo::swap, because the function
                     //is declared in the foo namespace??
    } 

}

【问题讨论】:

  • 参数依赖查找没有效果,你的模板太贪心了。
  • @DieterLucking 你是说我应该说使用 foo::swap;在功能中使其更加慈善?
  • 你为什么不简单地用std::cout &lt;&lt; "Hello world" 语句测试它?
  • @DeiDei 您在命名空间 foo 中 - 因此选择了贪婪的 foo::swap。
  • @LightnessRacesInOrbit 问题是,我有一个更大的代码库。有时我会得到“对函数的调用不明确”,这是通过在其前面添加命名空间范围来解决的。在我假设项目结构中存在其他问题之前,我想确保这是正确的。

标签: c++ c++11 namespaces


【解决方案1】:

这完全取决于T 的类型。

如果T 的类型位于具有自己的交换的不同命名空间中,则依赖于参数的查找将找到不同的swap()。否则它将在当前命名空间中查找。

#include <utility>  //includes std::swap and std::move
#include <iostream>

namespace foo
{
    template<typename T>
    inline void swap(T& lhs, T& rhs) {
        std::cout << "foo swap\n";
    }
}
namespace foo
{
    template<typename T>
    void myfun(T a, T b)
    {
        a += b;
        swap(a, b);  // Looks for swap using the type T.
                     // If not found uses the current namespace.
                     // If not found uses the enclosing namespace.
    }

}

namespace baz
{
    class X {
        public:
        X& operator+=(X const& rhs){return *this;}
    };
    inline void swap(X& lhs, X& rhs) {
        std::cout << "Bazz Swap\n";
    }
}

int main()
{
    baz::X  a,b;
    foo::myfun(a,b);  // finds ::baz::swap()
}

结果:

> a.out
Bazz Swap
>

【讨论】:

  • 正如我编译了一个示例并准备显示此答案已发布。
【解决方案2】:

它将调用foo::swap
如果你想使用std 实现,你可以使用std::swap(a, b);

【讨论】:

    【解决方案3】:

    是的,当然。首先在当前命名空间中搜索不合格的名称。

    【讨论】:

      【解决方案4】:

      它将调用foo::swap()。有一个常用的成语,就是写

      using std::swap;
      swap( x, y );
      

      在通用代码中。这使得std::swap 实现能够启动。但它还考虑了swap() 函数,这些函数通过参数相关查找(ADL)在其他命名空间中找到。因此,如果有一个函数foo::swap 并且xy 的类型在namespace foo 中,那么如果它比std::swap 更好匹配,则将调用这个foo::swap

      【讨论】:

        猜你喜欢
        • 2015-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多