繁体   English   中英

VS2012中的ADL错误?

[英]ADL bug in VS2012?

我怀疑以下是编译器错误,但我正在寻找验证。 我看过其他与此类似但又不完全匹配的问题。

这是代码:

namespace my {
  // using std::swap;

  // Convenience utility
  template<typename T> void doSwap(T& l, T& r)
  {
    using namespace std;
    swap(l,r);
  }

  template<typename T> struct Container 
  {
    T t;
    void swap(Container<T>& r) { doSwap(this->t,r.t); }
  };

  // Specialize swap() for Container<T>
  template<typename T> void swap(Container<T>& l, Container<T>& r)
  { l.swap(r); }
}

void stuff()
{
  my::Container<int> one;
  my::Container<int> two;

  one.swap(two);
}

当我使用Visual Studio 2012进行编译时,出现以下错误:

error C2784: 'void my::swap(my::Container<T> &,my::Container<T> &)' : could not deduce template argument for 'my::Container<T> &' from 'int'
see reference to function template instantiation 'void my::doSwap<T>(T &,T &)' being compiled
          with
          [
              T=int
          ]

如果取消注释我的命名空间顶部的using std::swap ,则可以正常工作。 无论哪种方式,相同的代码都可以在clang和g ++下编译,而无需发出警告。

是的,此代码有效。 但是您using namespace std; 应该using std::swap; 当前在您的代码中,就好像已在全局范围内声明了std::swap函数(因为这是同时包含stdmy的最小包围范围)。对于using namespace指令,所有声明在该范围内均可见)。 如果您在doSwap之前移动了另一个swap重载,那么Clang和GCC也会失败。

template<.....> void swap(....); // from namespace std

namespace my {
  // using std::swap;

  // Convenience utility
  template<typename T> void doSwap(T& l, T& r)
  {
    using namespace std;
    swap(l,r);
  }

  // ...

在原始代码中,在符合Standards的编译器上,这应该查找一次swap ,并在全局名称空间中找到swap 然后,在实例化时应再次查看调用,并注意调用参数为int ,并且int不可能实现ADL。 在实例化时,不允许再次进行常规查找,而只能再次进行ADL。 因此,结果将仍然是全局swap并且一切正常。

但是MSVC似乎也在实例化时也在进行正常的调用查找(可能是由于其模板解析模型。MSVC不会在定义模板时解析模板,而仅在使用具体类型实例化时解析)。 也许当时可见swap命名空间内过载my干涉,阻止考虑全局查找swap

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM