我想在c ++中使用模板

时间:2016-05-10 01:21:39

标签: c++

#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;
}

但是,我收到编译错误。有人可以帮我找到这个问题的解决方案吗?

4 个答案:

答案 0 :(得分:5)

您的问题是using namespace std

这是为什么&#34;使用命名空间std;&#34;当你最不希望它带来误导性和混乱的错误信息时,你会搞砸。

删除&#34;使用命名空间std&#34;从您的代码中,并始终明确指定&#34; std&#34;需要时,即std::cinstd::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

这是因为swapnamespace std的一部分。
因为你是using namespace std; - 这是不明确的!

您可以通过以下方式解决此问题:

1.删除第using namespace std;

2.将模板功能重命名为其他内容

答案 3 :(得分:0)

您的代码中存在许多导致错误消息的问题。由于您的实施(即您正在使用的标准库)而导致问题的一个原因。

首先,您已经使用相同的表单(通过引用接受两个相同类型的对象)定义了一个模板swap()作为名为swap()的现有函数。

其次,using namespace std告诉编译器命名空间std中的名称是代码中匹配名称的候选者。因此,当编译器看到您的代码swap(m,n) mnint时,它会看到您的定义和名称空间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()中查看名称作为候选者。它确实需要为您打算使用的名称空间stdstd::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; } ,这不值得在出现其他歧义问题时引起的麻烦。