在C++;,如何编写一个函数,使它可以在任何数据类型上工作? 我正在使用这个资源学习C++ STL:
下面给出了反转阵列元素的函数:在C++;,如何编写一个函数,使它可以在任何数据类型上工作? 我正在使用这个资源学习C++ STL:,c++,stl,iterator,C++,Stl,Iterator,下面给出了反转阵列元素的函数: template<typename T> void reversearr(T *begin, T *end) { // We should at first decrement 'end' // But only for non-empty range if(begin != end) { end--; if(begin != end) {
template<typename T> void reversearr(T *begin, T *end) {
// We should at first decrement 'end'
// But only for non-empty range
if(begin != end)
{
end--;
if(begin != end) {
while(true) {
swap(*begin, *end);
begin++;
if(begin == end) {
break;
}
end--;
if(begin == end) {
break;
}
}
}
}
}
但它给出了以下编译器错误:
迭代器02_ReverseIterators.cpp:39:32:错误:调用“reversearr(std::vector::iterator,std::vector::iterator)”时没有匹配的函数
如果我使用此代码:
vector<int> v;
//Code to insert data in vector
reversearr(v.begin(),v.end());
向量v;
//在矢量中插入数据的代码
反向耳环(v.begin(),v.end());
如何编写类似的函数,以便它们也可以在迭代器上工作?Welp,cppreference.com再次为我们提供了完整的答案,也称为: 可能的实施:
template<class BidirIt>
void reverse(BidirIt first, BidirIt last)
{
while ((first != last) && (first != --last)) {
std::iter_swap(first++, last);
}
}
模板
无效反向(第一个BidirIt,最后一个BidirIt)
{
while((first!=last)&(first!=last)){
标准:国际热核聚变实验堆交换(第一次++,最后一次);
}
}
其中,
BidirIt
是一个类型的概念。标准库容器的迭代器和原始指针都满足它,这就是它工作的原因。在代码中,参数是T
的指针。当您使用迭代器时,参数是指向迭代器的指针,因此它不起作用
如果您希望它与迭代器一起工作,我认为您应该这样编写:
template<typename T>
void reversearr(T begin, T end)
{
...
}
模板
无效反向耳环(T开始,T结束)
{
...
}
这里有一个有趣的事实:
即使从参数中删除*
,代码也可以与数组一起工作
template<typename T> void reversearr(T begin, T end) {
template void reversearl(T begin,T end){
为什么?
因为在原始代码中,T
是int
,函数参数的T*
是int*
在我修改的代码中,
T
是int*
,函数参数仍然是int*
这个“版本”适用于迭代器-选择了迭代器的语法和语义,因此您可以编写与指针或迭代器同样有效的泛型函数。“但它会导致编译器错误”错误是什么?要使用STL模型。这些抽象了指针的概念,因此您通常可以对它们进行递增、取消引用等操作。查看中的函数。对于类似的简单操作,您可以看到它如何在各种容器上工作。(我不会回答这个问题,因为你最好的选择是阅读互联网其他部分的材料。)抱歉,编辑为包含错误
T*
很可能是罪魁祸首。处理任何数据类型都将是一个挑战。反转单个链接列表并不容易,因为您缺少--
,只能使用++
。谢谢@Bartek Banachewicz!是的,这正是我想要的。但我不明白它是如何实现的工作。你能给我提供一个链接吗?@user2916888我发布的两个链接(特别是第二个)应该说清楚。如果他们不清楚,你可能需要回到你的书中,重新阅读关于标准容器和迭代器的章节。@user2916888除了这里已经发布的内容外,你还可以看看。我相信这会让事情变得足够清楚。哦,我没意识到它这么简单!:P谢谢@wangxf:)不过,仅供参考,不要使用像t
:)这样的名称,选择一个写着“嘿,我是某种迭代器”的名称@cHao,同意!:)但我使用了“T”,因为我只是在学习概念,而不是实际开发:)@user2916888:命名不是在事实之后,而是在它之前。如果您将类型命名为“Iterator”,那么很明显,“Iterator*”不是参数的类型。命名将帮助您理解您的cod大卫·罗德里格斯,我同意,但你看,它甚至不是我自己的代码。我直接从我学习的源代码中获取它。(Topcoder)谢谢molbdnilo。是的,在@wangfx给出同样的答案后,我意识到了这一点:)
template<typename T> void reversearr(T begin, T end) {