在方法中迭代向量
Iterate vector inside method
我目前正在学习 C++,我有以下工作代码:
int main(int argc, char** argv) {
map<unsigned int, list<mpz_class>> otp;
// .....
for(auto it1 = otp.begin(); it1 != otp.end(); ++it1) {
bool first = true;
for(auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2) {
if (!first) {
cout << ", ";
} else {
first = false;
}
cout << *it2;
}
}
}
我想把列表的打印放到一个函数中。
这是我的尝试:
void prnt_list(vector it, ostream outstr, string delimiter) {
bool first = true;
for(auto it2 = it.begin(); it2 != it.end(); ++it2) {
if (!first) {
outstr << delimiter;
} else {
first = false;
}
outstr << *it2;
}
}
int main(int argc, char** argv) {
map<unsigned int, list<mpz_class>> otp;
// .....
for(auto it1 = otp.begin(); it1 != otp.end(); ++it1) {
prnt_list(it1->second, cout, ", ");
}
)
编译不通过:
error: variable or field 'prnt_list' declared void
error: missing template arguments before 'it'
error: expected primary-expression before 'outstr'
error: expected primary-expression before 'delimiter'
然后我试了这个:
template <typename T>
void prnt_list<T>(vector<T> it, ostream outstr, string delimiter) {
...
}
但是还是不行。
此外,我也不喜欢强制模板,因为我想允许任何向量。如果我能以某种方式使用 auto
关键字,那会舒服得多。
您正在向需要 vector
的函数发送 list
泛型可能如下所示:
template <typename T>
void prnt_list(const T& it, std::ostream& outstr, const std::string& delimiter)
{
bool first = true;
for( auto&& obj : it ) {
if (!first)
outstr << delimiter;
else
first = false;
outstr << obj;
}
}
另请注意,必须为 mpz_class
定义 <<
它需要 headers <string>
和 <iostream>
问题是:
map<unsigned int, list<mpz_class>> otp;
第二个是列表,prnt_list的第一个参数是向量。为什么?
要修复这些错误,请为 prnt_list 使用以下签名:
template<typename T>
void prnt_list(list<T>& it, ostream& outstr, string delimiter) {
函数可以这样定义
std::ostream & prnt_list( const std::list<mpz_class> &lst,
std::ostream &os = std::cout,
const char *delimiter = ", " )
{
bool first = true;
for ( const auto &obj : lst )
{
if ( first ) first = false;
else os << delimiter;
os << obj;
}
return os;
}
并称赞
for ( const auto &p : otp ) prnt_list( p.second ) << std::endl;
您可以为任何容器编写通用函数。例如
template <class Container>
std::ostream & prnt_list( const Container &container,
std::ostream &os = std::cout,
const char *delimiter = ", " )
{
bool first = true;
for ( const auto &obj : container )
{
if ( first ) first = false;
else os << delimiter;
os << obj;
}
return os;
}
至于你的代码,至少没有声明标识符向量,并且流是不可复制的。
扩展 Vlad 的回答 - 允许 print_list 参与 ostream
<<
链:
#include <iostream>
#include <list>
namespace detail {
// it's called a simple list printer because it assumes that
// list::value_type is printable
template<class T, class A>
struct simple_list_printer {
simple_list_printer(const std::list<T, A>& list, std::string delimiter)
: _list { list }
, _delimiter { delimiter }
{}
void write(std::ostream& os) const {
bool first = true;
for ( const auto &obj : _list )
{
if ( first ) first = false;
else os << _delimiter;
os << obj;
}
}
private:
const std::list<T, A>& _list;
std::string _delimiter;
};
// stream an simple_list_printer to any ostream
template<class T, class A>
inline std::ostream& operator<<(std::ostream& os, const simple_list_printer<T, A>& slp)
{
slp.write(os);
return os;
}
}
// a mockup of mpz_class
struct mpz_class {
void write(std::ostream& os) const {
os << "{ i am an mpz - write my members here }";
}
};
// stream an mpz to any ostream
inline std::ostream& operator<<(std::ostream& os, const mpz_class& mpz)
{
mpz.write(os);
return os;
}
// construct a simple_list_printer
template<class A>
detail::simple_list_printer<mpz_class, A>
print_list(const std::list<mpz_class, A>& list, std::string delimiter = std::string { ", " })
{
return { list, std::move(delimiter) };
}
int main()
{
std::list<mpz_class> a { {}, {} };
std::cout << print_list(a) << std::endl;
std::cerr << print_list(a) << std::endl;
std::clog << print_list(a) << std::endl;
std::cout << print_list(a, "\n") << std::endl;
std::cout << std::endl;
std::cerr << print_list(a, " * ") << std::endl;
std::clog << print_list(a, " <--> ") << std::endl;
return 0;
}
预期输出:
{ i am an mpz - write my members here }, { i am an mpz - write my members here }
{ i am an mpz - write my members here }, { i am an mpz - write my members here }
{ i am an mpz - write my members here }, { i am an mpz - write my members here }
{ i am an mpz - write my members here }
{ i am an mpz - write my members here }
{ i am an mpz - write my members here } * { i am an mpz - write my members here }
{ i am an mpz - write my members here } <--> { i am an mpz - write my members here }
我目前正在学习 C++,我有以下工作代码:
int main(int argc, char** argv) {
map<unsigned int, list<mpz_class>> otp;
// .....
for(auto it1 = otp.begin(); it1 != otp.end(); ++it1) {
bool first = true;
for(auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2) {
if (!first) {
cout << ", ";
} else {
first = false;
}
cout << *it2;
}
}
}
我想把列表的打印放到一个函数中。
这是我的尝试:
void prnt_list(vector it, ostream outstr, string delimiter) {
bool first = true;
for(auto it2 = it.begin(); it2 != it.end(); ++it2) {
if (!first) {
outstr << delimiter;
} else {
first = false;
}
outstr << *it2;
}
}
int main(int argc, char** argv) {
map<unsigned int, list<mpz_class>> otp;
// .....
for(auto it1 = otp.begin(); it1 != otp.end(); ++it1) {
prnt_list(it1->second, cout, ", ");
}
)
编译不通过:
error: variable or field 'prnt_list' declared void
error: missing template arguments before 'it'
error: expected primary-expression before 'outstr'
error: expected primary-expression before 'delimiter'
然后我试了这个:
template <typename T>
void prnt_list<T>(vector<T> it, ostream outstr, string delimiter) {
...
}
但是还是不行。
此外,我也不喜欢强制模板,因为我想允许任何向量。如果我能以某种方式使用 auto
关键字,那会舒服得多。
您正在向需要 vector
的函数发送 list
泛型可能如下所示:
template <typename T>
void prnt_list(const T& it, std::ostream& outstr, const std::string& delimiter)
{
bool first = true;
for( auto&& obj : it ) {
if (!first)
outstr << delimiter;
else
first = false;
outstr << obj;
}
}
另请注意,必须为 mpz_class
<<
它需要 headers <string>
和 <iostream>
问题是:
map<unsigned int, list<mpz_class>> otp;
第二个是列表,prnt_list的第一个参数是向量。为什么?
要修复这些错误,请为 prnt_list 使用以下签名:
template<typename T>
void prnt_list(list<T>& it, ostream& outstr, string delimiter) {
函数可以这样定义
std::ostream & prnt_list( const std::list<mpz_class> &lst,
std::ostream &os = std::cout,
const char *delimiter = ", " )
{
bool first = true;
for ( const auto &obj : lst )
{
if ( first ) first = false;
else os << delimiter;
os << obj;
}
return os;
}
并称赞
for ( const auto &p : otp ) prnt_list( p.second ) << std::endl;
您可以为任何容器编写通用函数。例如
template <class Container>
std::ostream & prnt_list( const Container &container,
std::ostream &os = std::cout,
const char *delimiter = ", " )
{
bool first = true;
for ( const auto &obj : container )
{
if ( first ) first = false;
else os << delimiter;
os << obj;
}
return os;
}
至于你的代码,至少没有声明标识符向量,并且流是不可复制的。
扩展 Vlad 的回答 - 允许 print_list 参与 ostream
<<
链:
#include <iostream>
#include <list>
namespace detail {
// it's called a simple list printer because it assumes that
// list::value_type is printable
template<class T, class A>
struct simple_list_printer {
simple_list_printer(const std::list<T, A>& list, std::string delimiter)
: _list { list }
, _delimiter { delimiter }
{}
void write(std::ostream& os) const {
bool first = true;
for ( const auto &obj : _list )
{
if ( first ) first = false;
else os << _delimiter;
os << obj;
}
}
private:
const std::list<T, A>& _list;
std::string _delimiter;
};
// stream an simple_list_printer to any ostream
template<class T, class A>
inline std::ostream& operator<<(std::ostream& os, const simple_list_printer<T, A>& slp)
{
slp.write(os);
return os;
}
}
// a mockup of mpz_class
struct mpz_class {
void write(std::ostream& os) const {
os << "{ i am an mpz - write my members here }";
}
};
// stream an mpz to any ostream
inline std::ostream& operator<<(std::ostream& os, const mpz_class& mpz)
{
mpz.write(os);
return os;
}
// construct a simple_list_printer
template<class A>
detail::simple_list_printer<mpz_class, A>
print_list(const std::list<mpz_class, A>& list, std::string delimiter = std::string { ", " })
{
return { list, std::move(delimiter) };
}
int main()
{
std::list<mpz_class> a { {}, {} };
std::cout << print_list(a) << std::endl;
std::cerr << print_list(a) << std::endl;
std::clog << print_list(a) << std::endl;
std::cout << print_list(a, "\n") << std::endl;
std::cout << std::endl;
std::cerr << print_list(a, " * ") << std::endl;
std::clog << print_list(a, " <--> ") << std::endl;
return 0;
}
预期输出:
{ i am an mpz - write my members here }, { i am an mpz - write my members here }
{ i am an mpz - write my members here }, { i am an mpz - write my members here }
{ i am an mpz - write my members here }, { i am an mpz - write my members here }
{ i am an mpz - write my members here }
{ i am an mpz - write my members here }
{ i am an mpz - write my members here } * { i am an mpz - write my members here }
{ i am an mpz - write my members here } <--> { i am an mpz - write my members here }