[英]Universal operator >> for std::vector
我剛剛了解了重載運算符並決定為std::vector
重載operator >>
。 我不確定這是否是正確的方法,但它有效。
void operator >> (istream &in, vector<int> &_vector)
{
int vectorSize;
cout << "Enter vector size\n";
cin >> vectorSize;
_vector = vector<int>(vectorSize);
cout << "Enter the array\n";
for (int &element : _vector)
in >> element;
}
但后來我意識到這種方法只適用於vector<int>
,不適用於其他向量。 如何使其通用並適用於任何向量?
以最小的變化:
template <class T>
void operator >> (istream &in, vector<T> &_vector)
{
int vectorSize;
cout << "Enter vector size\n";
cin >> vectorSize;
_vector = vector<T>(vectorSize);
cout << "Enter the array\n";
for (T &element : _vector)
in >> element;
}
請注意,您應該對代碼進行許多改進:使用std::size_t
,使用std::vector::resize()
,避免在運算符中使用std::cin/cout
,避免using namespace std;
,返回適當的類型,避免以_
開頭的標識符(即使在這里有效)......加上他們在問題評論中告訴你的 rest 也是。
我對此感到很開心。 這是我的:
源文件 json-style-vector-input.cpp:
#include <vector>
#include <iostream>
#include <utility>
#include <string_view>
#include <string>
using namespace std::literals;
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T> &v) {
std::string_view separator = "";
constexpr std::string_view comma = ", ";
os << '[';
for(const auto &i: v) {
os << separator;
separator = comma;
os << i;
}
os << ']';
return os;
}
template<typename T>
std::istream& operator>>(std::istream& is, std::vector<T> &v) {
char c;
is >> c;
if(c != '[') {
is.setstate(std::ios::failbit);
return is;
}
v.clear();
bool done = false;
while(!done) {
T tmp;
is >> tmp;
if(!is) return is;
v.push_back(std::move(tmp));
is >> c;
if(!is) return is;
if(c == ']') {
done = true;
} else if(c != ',') {
is.setstate(std::ios::failbit);
done = true;
}
}
return is;
}
std::ostream& operator<<(std::ostream &os, const std::ios::iostate &state) {
using std::ios;
if(state == ios::goodbit) os << "goodbit"sv;
if((state & ios::badbit) == ios::badbit) os << "badbit"sv;
if((state & ios::failbit) == ios::failbit) os << "failbit"sv;
if((state & ios::eofbit) == ios::eofbit) os << "eofbit"sv;
return os;
}
template<typename Ch = char>
class quoted_string : public std::basic_string<Ch> {
};
template<typename Ch>
std::istream& operator>>(std::istream &is, quoted_string<Ch> &s) {
char c;
is >> c;
if(!is) return is;
if(c != '"') {
is.setstate(std::ios::failbit);
return is;
}
std::getline(is, s, '"');
while(s.length() > 0 && s[ s.length()-1 ] == '\\') {
s[ s.length()-1 ] = '"';
std::basic_string<Ch> more;
std::getline(is, more, '"');
s += more;
}
return is;
}
template<typename Ch>
std::ostream& operator<<(std::ostream &os, const quoted_string<Ch> &s) {
os << '"';
if( s.find('"') != std::basic_string<Ch>::npos ) {
for( const auto& c: s ) {
if( c == '"' ) os << '\\';
os << c;
}
} else {
os << static_cast<std::basic_string<Ch>>(s);
}
os << '"';
return os;
}
int main() {
std::ios::sync_with_stdio(false);
std::vector<int> a;
std::cin >> a;
if(!std::cin) {
std::cout << "input failure: "sv << std::cin.rdstate() << std::endl;
std::cin.clear();
}
std::cout << a << std::endl;
std::vector<quoted_string<char>> b;
std::cin >> b;
if(!std::cin) {
std::cout << "input failure: "sv << std::cin.rdstate() << std::endl;
std::cin.clear();
}
std::cout << b << std::endl;
return 0;
}
構建命令(Linux):
g++ -Wall -W -pedantic -g -pthread -O3 -flto -fno-fat-lto-objects -std=c++17 -pthread json-style-vector-input.cpp -o json-style-vector-input
測試文件test2.txt:
[1,99,2222]
["fred", "string with spaces", "", "another space string",
"string \"string\" string"]
測試命令:
$ ./json-style-vector-input <test2.txt
[1, 99, 2222]
["fred", "string with spaces", "", "another space string", "string \"string\" string"]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.