#include <iostream>
using namespace std;
template <typename T>
void swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
swap(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}
但是,我收到编译错误。有人可以帮我找到这个问题的解决方案吗?
答案 0 :(得分:5)
您的问题是using namespace std。
这是为什么&#34;使用命名空间std;&#34;当你最不希望它带来误导性和混乱的错误信息时,你会搞砸。
删除&#34;使用命名空间std&#34;从您的代码中,并始终明确指定&#34; std&#34;需要时,即std::cin
,std::cout
等......
你需要保证自己永远不会写'#34;使用命名空间std&#34;以后再。完全忘记这是C ++语言的一部分。
您的程序的固定版本,编译没有任何问题,只是:
#include <iostream>
template <typename T>
void swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
std::cout << "Inputs: " << m << "," << n << std::endl;
swap(m, n);
std::cout << "Outputs: " << m << "," << n << std::endl;
return 0;
}
答案 1 :(得分:1)
swap()已经是std命名空间中的已定义函数。将您的方法重命名为其他内容。
using namespace std;
template <typename T>
void swaper(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
swaper(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}
答案 2 :(得分:0)
错误消息清楚地表明:error: call to 'swap' is ambiguous
。
这是因为swap
是namespace std
的一部分。
因为你是using namespace std;
- 这是不明确的!
您可以通过以下方式解决此问题:
1.删除第using namespace std;
行
2.将模板功能重命名为其他内容
答案 3 :(得分:0)
您的代码中存在许多导致错误消息的问题。由于您的实施(即您正在使用的标准库)而导致问题的一个原因。
首先,您已经使用相同的表单(通过引用接受两个相同类型的对象)定义了一个模板swap()
作为名为swap()
的现有函数。
其次,using namespace std
告诉编译器命名空间std
中的名称是代码中匹配名称的候选者。因此,当编译器看到您的代码swap(m,n)
m
和n
为int
时,它会看到您的定义和名称空间std
中的定义(即{ {1}}作为匹配代码中std::swap()
名称的可行候选者。两个候选者都能够接受两个类型(引用)swap()
的参数,因此编译器没有理由更喜欢一个因此,它会拒绝您的代码,并提供有关歧义的错误消息。
第三个问题出现在您的实现中(即您的编译器及其相关的标准库) - int
显然已在<iostream>
的定义中绘制。问题是std::swap()
既不需要这样做(即如果用不同的编译器构建代码就不能依赖它),也不要求不这样做(即你的代码可以用一些编译器/库编译好但是不是其他人。)
实际上,标准要求<iostream>
在std::swap()
中声明,而不是<algorithm>
。
因此,使用所有编译器处理代码的选项非常简单。第一个选择是根本不定义您自己的<iostream>
,并依赖标准库。
swap()
第二个选项是重命名您的功能,使其不与#include <iostream>
#include <algorithm> // Needed to guarantee visibility of std::swap()
using namespace std;
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
swap(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}
冲突。
std::swap()
第三个选项是从代码中删除#include <iostream>
using namespace std;
template <typename T>
void your_swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
cout << "Inputs: " << m << "," << n << endl;
your_swap(m, n);
cout << "Outputs: " << m << "," << n << endl;
return 0;
}
。这样您就可以安全地声明自己的using namespace std
,而不会与swap()
发生冲突。
std::swap()
这最后一个例子实际上很好地编译 - 即使#include <iostream>
#include <algorithm>
template <typename T>
void swap(T& i, T& j)
{
T temp = i;
i = j;
j = temp;
}
int main()
{
int m = 5, n = 10;
std::cout << "Inputs: " << m << "," << n << std::endl;
swap(m, n);
std::cout << "Outputs: " << m << "," << n << std::endl;
return 0;
}
故意用于绘制<algorithm>
的声明 - 因为编译器没有被告知在std::swap()
中查看名称作为候选者。它确实需要为您打算使用的名称空间std
(std::
,std
)中的名称添加std::cout
前缀。如果std::endl
替换为swap(m,n)
,它也会很好地编译。
第四种选择(我通常更倾向于专业编码)是依靠标准库而不是std::swap(m,n)
。
using namespace std
我对此选项的偏好的简短解释是它避免了其他各种歧义问题。保存的输入不必在名称前加#include <iostream>
#include <algorithm> // Needed to guarantee visibility of std::swap()
int main()
{
int m = 5, n = 10;
std::cout << "Inputs: " << m << "," << n << std::endl;
std::swap(m, n);
std::cout << "Outputs: " << m << "," << n << std::endl;
return 0;
}
,这不值得在出现其他歧义问题时引起的麻烦。