Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ VS2012中的ADL缺陷?_C++_Templates_Visual Studio 2012 - Fatal编程技术网

C++ VS2012中的ADL缺陷?

C++ VS2012中的ADL缺陷?,c++,templates,visual-studio-2012,C++,Templates,Visual Studio 2012,我怀疑以下是一个编译器错误,但我正在寻找验证。我见过其他类似的问题,但并不完全匹配 代码如下: 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>

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

代码如下:

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);
}
名称空间我的{
//使用std::swap;
//方便实用程序
模板无效doSwap(T&l、T&r)
{
使用名称空间std;
互换(l,r);
}
模板结构容器
{
T;
无效交换(容器&r){doSwap(this->t,r.t);}
};
//为容器专门化swap()
模板无效交换(容器和l、容器和r)
{l.swap(r);}
}
空的东西
{
我的::容器一;
我的……容器二;
一,互换(二);;
}
当我使用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
          ]
错误C2784:'void my::swap(my::Container&,my::Container&'):无法从'int'推断'my::Container&'的模板参数
请参阅正在编译的函数模板实例化“void my::doSwap(T&,T&)”的参考
具有
[
T=int
]

若我使用名称空间顶部的std::swap取消对
的注释,它就会工作。无论哪种方式,相同的代码在clang和g++下编译,甚至没有任何警告。

是的,此代码有效。但是您的
使用名称空间std应该是
使用std::swap。当前在您的代码中,就好像一个
std::swap
函数已在全局范围内声明(因为这是包含
std
my
的最小封闭范围。对于
使用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);
  }

  // ...
模板无效交换(..);//从命名空间std
名称空间我的{
//使用std::swap;
//方便实用程序
模板无效doSwap(T&l、T&r)
{
使用名称空间std;
互换(l,r);
}
// ...
在符合标准的编译器上的原始代码中,这应该查找一次
swap
,并在全局命名空间中找到
swap
。然后在实例化时,它应该再次查看调用,并注意调用参数是
int
,并且
int
不可能有ADL。在实例化时,n不允许再次执行正常查找,只能执行ADL。因此,结果将保持全局
交换
,一切正常


但MSVC似乎也在实例化时对调用执行正常的查找(pobably是因为它的模板解析模型。MSVC在定义模板时不解析模板,而仅在使用具体类型实例化模板时才解析)。可能命名空间
my
中可见的
swap
重载干扰并阻止了全局
swap

的查找。我不确定“使用std::swap”和“使用命名空间std”之间的区别,因为它适用于此处,但可以肯定的是,它确实起到了作用。谢谢!