首页 > 解决方案 > C++“使用命名空间”追溯可见性?

问题描述

我设置了一些代码来检测同名的方法或函数,并调用适当的方法或函数,或者abort两者都不存在。但是,我注意到,如果调用此方法的编译单元通过 导入命名空间using,则结果是无限递归而不是abort. using从前面的标题中可以看出,源文件中的声明似乎是追溯添加到全局命名空间中的,我觉得这很令人不安。

我已尽我所能在此处隔离问题以进行说明(使用 MSVC2017 编译):

// HEADER

namespace ns1
{
  template<typename U>
  inline auto foo_free(const U& u, int)
    -> decltype(foo(u))
  {
    return foo(u);
  }

  template<typename U>
  inline uint64_t foo_free(const U& u, char)
  {
    abort();
    return 0;
  }

  template<typename U>
  inline auto foo_method(const U& u, int)
    -> decltype(u.foo())
  {
    return u.foo();
  }

  template<typename U>
  inline uint64_t foo_method(const U& u, char)
  {
    return ns1::foo_free(u, 0);
  }
}

namespace ns2
{
  template<typename U>
  inline uint64_t foo(const U& u)
  {
    return ns1::foo_method(u, 0);
  }
}

// SOURCE

// removing this line results in expected behavior
using namespace ns2;

struct atype {};

bool detect_foo_confusion(void)
{
  atype a;
  const atype* cap = &a;
  ns2::foo(cap); // problem
  return true;
}

我能想到的唯一解决方案是命名ns2::foo或其他foo不同的东西,但这会对调用代码的外观产生一些不良后果。

  1. 这里发生了什么?using namespace总是以这种方式工作,还是这是模板的事情?
  2. 有没有办法让我隔离ns1ns2保持相同的名字?

标签: c++templatesnamespaces

解决方案


推荐阅读