为啥我在使用 STL 列表时不能使用这个回文函数?
Posted
技术标签:
【中文标题】为啥我在使用 STL 列表时不能使用这个回文函数?【英文标题】:Why can't I use this palindrome function when using an STL list?为什么我在使用 STL 列表时不能使用这个回文函数? 【发布时间】:2020-03-04 15:57:30 【问题描述】:我创建了一个回文函数,它允许我使用任何容器类型,它适用于字符串、向量和双端队列,但是当我创建一个 STL 列表并尝试运行代码时,我得到了下面的错误,我不能'不知道这意味着什么以及该怎么做。
Severity Code Description Project File Line Suppression State
Error C2676 binary '-': 'std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>' does not define this operator or a conversion to a type acceptable to the predefined operator homework4 C:\...\Source.cpp 9
Severity Code Description Project File Line Suppression State
Error C3536 'itr1': cannot be used before it is initialized homework4 C:\...\Source.cpp 9
Severity Code Description Project File Line Suppression State
Error C2676 binary '<': 'std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>' does not define this operator or a conversion to a type acceptable to the predefined operator homework4 C:\...\Source.cpp 9
Severity Code Description Project File Line Suppression State
Error C2100 illegal indirection homework4 C:\...\Source.cpp 10
Visual studio error list
在我运行的代码下方。
#include <iostream>
#include<list>
#include<vector>
#include<deque>
using namespace std;
template <typename Container>
bool palindrome(const Container& s)
for (auto itr = s.begin(), itr1 = s.end() - 1; itr < itr1; itr++, itr1--)
if (*itr != *itr1)
return false;
return true;
void main()
const string word1 "racecar" ;
const vector<char> word2 'a', 'b', 'b', 'a' ;
const deque<int> word3 83, 84, 65, 84, 83 ;
const list<int> word4 83, 84, 65, 84, 83 ;
word4.end();
cout << palindrome< string >(word1) << endl;
cout << palindrome< vector<char> >(word2) << endl;
cout << palindrome< deque<int> >(word3) << endl;
cout << palindrome< list<int> >(word4) << endl;
【问题讨论】:
将s.end() - 1
替换为std::prev(s.end())
。前者需要一个随机访问迭代器,而列表迭代器则不需要。
对s.rbegin()
和s.rend()
的第二种情况使用反向迭代器
另外,以后如果你需要以通用方式做这样的事情,请使用std::next
、std::advance
、std::distance
等。
@IgorTandetnik 对于列表迭代器,itr < itr1
也会有问题,因为 <
运算符也没有为此定义。
@AdrianMole 真的。需要类似itr != itr1 && itr != std::next(itr1)
【参考方案1】:
标准容器 std::list 具有双向迭代器。运算符 - 在这个表达式中使用
itr1 = s.end() - 1
是为随机访问迭代器定义的。您可以改用在标头<iterator>
中声明的标准函数std::prev
,例如
itr1 = std::prev( s.end() )
但是在任何情况下该函数都是无效的,因为通常该函数的用户可以传递一个空容器。在这种情况下,表达式 std::prev( s.end() )
具有未定义的行为。
并且操作符
itr < itr1
也不能在函数中使用。
此外,该函数不适用于数组,因为数组没有成员函数,例如 begin()
。
该函数可以如下面的演示程序所示。
#include <iostream>
#include <iomanip>
#include <string>
#include <deque>
#include <vector>
#include <list>
#include <iterator>
template <typename Container>
bool palindrome( const Container &c )
auto first = std::begin( c );
auto last = std::end( c );
while ( first != last && first != --last && *first == *last ) ++first;
return first == last;
int main()
const std::string word1 "racecar" ;
const std::vector<char> word2 'a', 'b', 'b', 'a' ;
const std::deque<int> word3 83, 84, 65, 84, 83 ;
const std::list<int> word4 83, 84, 65, 84, 83 ;
const char word5[] = 83, 84, 65, 84, 83 ;
std::cout << std::boolalpha << palindrome( word1 ) << '\n';
std::cout << std::boolalpha << palindrome( word2 ) << '\n';
std::cout << std::boolalpha << palindrome( word3 ) << '\n';
std::cout << std::boolalpha << palindrome( word4 ) << '\n';
std::cout << std::boolalpha << palindrome( word5 ) << '\n';
return 0;
程序输出是
true
true
true
true
true
如果您愿意,您可以将函数专门用于随机访问迭代器。
【讨论】:
非常聪明的循环条件!const char *
转换为 std::string
或 std::string_view
可能需要专门化以上是关于为啥我在使用 STL 列表时不能使用这个回文函数?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能使用 folium.Map() 函数在地图中标记值列表?