我有以下代码:
//code.h
#include<string>
#include<iterator>
#include<iostream>
using std::string;
using std::advance;
using std::iterator;
using std::cin;
using std::cout;
using std::endl;
bool chk_if_uniq (string);
bool per_scan(iterator,iterator);
//code.cpp
#ifndef CODE_H
#define CODE_H
#include "code.h"
#endif
int main (){
string input_string;
cout << "enter string: ";
cin >> input_string;
auto result = chk_if_uniq(input_string);
if(result){
cout << input_string << " contains unique characters." << endl;
}
else{
cout << input_string << " contains non-unique characters." << endl;
}
return 0;
}
bool chk_if_uniq (string s){
auto bIter = s.begin();
auto eIter = s.end();
bool iterPos = (bIter != eIter);
auto flag = true;
while(iterPos){
flag = per_scan(bIter,eIter);
if(!flag){
break;
}
advance(bIter,1);
}
return flag;
}
bool per_scan(iterator it, iterator eIter){
auto nxIt = it;
bool iterPos = (nxIt != eIter);
auto flag = true;
do{
++nxIt;
if(iterPos){
if(*nxIt == *it){
flag = false;
}
}
}while(flag);
return flag;
}
我有以下编译命令:
g++ -ggdb -g3 -o -pedantic-errors -std=c++17 -Wall -Wextra -Wpedantic
我使用的gcc版本是8.4.1。
我收到以下编译器错误:
In file included from code.cpp:3:
code.h:13:15: error: ‘auto’ parameter not permitted in this context
bool per_scan(iterator,iterator);
^~~~~~~~
code.h:13:24: error: ‘auto’ parameter not permitted in this context
bool per_scan(iterator,iterator);
^~~~~~~~
code.cpp: In function ‘bool chk_if_uniq(std::__cxx11::string)’:
code.cpp:33:31: error: too many arguments to function ‘bool per_scan()’
flag = per_scan(bIter,eIter);
^
In file included from code.cpp:3:
code.h:13:6: note: declared here
bool per_scan(iterator,iterator);
^~~~~~~~
code.cpp: At global scope:
code.cpp:43:24: error: ‘auto’ parameter not permitted in this context
bool per_scan(iterator it, iterator eIter){
^~
code.cpp:43:37: error: ‘auto’ parameter not permitted in this context
bool per_scan(iterator it, iterator eIter){
^~~~~
code.cpp: In function ‘bool per_scan()’:
code.cpp:45:15: error: ‘it’ was not declared in this scope
auto nxIt = it;
^~
code.cpp:45:15: note: suggested alternative: ‘int’
auto nxIt = it;
^~
int
code.cpp:46:27: error: ‘eIter’ was not declared in this scope
bool iterPos = (nxIt != eIter);
^~~~~
code.cpp:46:27: note: suggested alternative: ‘extern’
bool iterPos = (nxIt != eIter);
^~~~~
extern
从错误日志中可以明显看出,所有错误都源于在头文件中使用
iterator
作为方法per_scan
的参数类型。
显然,我对迭代器概念的理解是有缺陷的。
有人可以指出使用上有什么问题吗?
蒂亚
是的,你的理解有缺陷。您对
std::iterator
模板的使用让人想起 Java 中的泛型,它们是具体类型的占位符。它们基于类型擦除。另一方面,模板可用于类型擦除,但它们并不是开箱即用的。类模板必须先实例化才能使用。函数的参数类型是类型,而不是模板。这个
bool per_scan(std::iterator,std::iterator);
std::iterator
不是一种类型。
此外,
std::iterator
旨在在实现自定义迭代器时用作帮助器。使用 std::iterator
的实例化作为函数参数很少有用,因为它将参数类型限制为 std::iterator
模板的实例化,但并非所有迭代器都适合这一点。实际上,我不知道标准库中有任何迭代器是 std::iterator
的实例化。迭代器的优点之一是大多数时候您不需要关心具体类型。例如 std::vector::iterator
可以实现为指针。你不用在意。
考虑如何声明标准算法等。迭代器的类型通常是一个模板参数,它不对实现细节做出任何假设(参见例如
std::find
)。实现的要求在命名要求中或通过概念定义 (C++20 起)。请参阅https://en.cppreference.com/w/cpp/named_req/Iterator。
将函数改为函数模板:
template <typename Iter>
bool per_scan(Iter it, Iter eIter){
auto nxIt = it;
bool iterPos = (nxIt != eIter);
auto flag = true;
do{
++nxIt;
if(iterPos){
if(*nxIt == *it){
flag = false;
}
}
}while(flag);
return flag;
}