我编写了这个简单的C ++代码来交换任何两个变量。它适用于int和double,但不适用于复数,任何想法为什么?
#include <iostream>
#include <complex>
using std::cout;
using std::endl;
using std::complex;
template <class T>
inline void swap(T& d, T& s)
{
T temp = d;
d = s;
s = temp;
}
int main()
{
int m=5, n=10;
double x=5.3, y=10.6;
complex<double> r(2.4, 3.5), s(3.4, 6.7);
cout << "inputs: " << m << " , " << n << endl;
swap(m, n);
cout << "outputs: " << m << " , " << n << endl;
cout << "double inputs: " << x << " , " << y << endl;
swap(x, y);
cout << "double outputs: " << x << " , " << y << endl;
cout << "complex inputs: " << r << " , " << s << endl;
swap(r, s);
cout << "complex outputs: " << r << " , " << s << endl;
}
这是错误:
g++ 02.swap.template.cpp -o c.out.02
02.swap.template.cpp: In function ‘int main()’:
02.swap.template.cpp:37:13: error: call of overloaded ‘swap(std::complex<double>&, std::complex<double>&)’ is ambiguous
02.swap.template.cpp:37:13: note: candidates are:
02.swap.template.cpp:13:13: note: void swap(T&, T&) [with T = std::complex<double>]
/usr/include/c++/4.6/bits/move.h:122:5: note: void std::swap(_Tp&, _Tp&) [with _Tp = std::complex<double>]
答案 0 :(得分:3)
name conflit,更改为:: swap解决了这个问题。
答案 1 :(得分:2)
问题在于,因为您正在调用函数 template ,所以应用参数依赖查找。如果你有一个简单的函数,就没有歧义:
#include <complex>
void swap(complex<double> & d, complex<double> & s)
{
complex<double> temp = d;
d = s;
s = temp;
}
int main()
{
std::complex<double> r(2.4, 3.5), s(3.4, 6.7);
swap(r, s);
}
这是因为C ++ 11 3.4.2:
让 X 成为非限定查找(3.4.1)生成的查找集,让 Y 成为由参数相关查找生成的查找集(定义如下)。如果 X 包含
- 类成员的声明,或
- 不是using声明的块范围函数声明,或
- 既不是函数也不是函数模板的声明
然后 Y 为空。否则 Y 是在与参数类型相关联的名称空间中找到的声明集,如下所述。通过查找名称找到的声明集是 X 和 Y 的并集。
在上面的例子中, X 包含一个块范围函数声明。
但是,如果非限定查找找到您提供的函数 template ,则ADL规则会说还会考虑依赖于参数的查找集。由于std::complex<double>
位于std
命名空间中,因此还会在此命名空间中搜索已存在的名称swap
(按照20.2.2)。
您可以通过将函数名称括在括号中来阻止依赖于参数的查找:
(swap)(r, s);
这样,只考虑非限定查找。
答案 2 :(得分:0)
编译器说它因两个函数而混淆:你的和标准的std :: swap。它也考虑std :: swap,因为std :: complex是std :: namespace的成员,它调用了Argument Dependent Lookup。如果要显式测试交换,可以使用:: scope resolution运算符,即:: swap而不是swap。它将进行另一种查找:合格的名称查找解决模糊性。
尽管如此,std :: swap运行良好并完成工作,除了练习,包括实用程序标准头,使用std :: swap,它将正常工作:
#include<utility>
//before needed (closest)
using std::swap;
swap(/*arguments*/);