重载功能不适用于复杂

时间:2013-11-06 01:05:13

标签: c++ templates

我编写了这个简单的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>]

3 个答案:

答案 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*/);