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”之间的区别,因为它适用于此处,但可以肯定的是,它确实起到了作用。谢谢!