Item 6: Be alert for C++’s most vexing parse.
read all word
std::vector<std::string> vs((std::istream_iterator<std::string>("somefilename")),
std::istream_iterator<std::string>());
read all line
std::vector<std::string> vs;
std::string somestring;
std::ifstream somefile("somefilename");
while (std::getline(somefile, somestring)) vs.push_back(somestring);
Item 9: Choose carefully among erasing options
/
remove single bad value
/
vector: c.erase(remove(c.begin(), c.end(), badvalue), c.end())
list: c.remove(badvalue)
map: c.erase(badkey)
/
remove bad value by condition: bool IsBad(int x)
/
vector: c.erase(remove(c.begin(), c.end(), IsBad), c.end())
list: c.remove_if(IsBad)
map:
map good;
remove_copy_if(org.begin() org.end(), inserter(good, good.end()), IsBadKey);
org.swap(good)
/
loop, proccess and remove
/
vector & list:
for(.. it = c.begin(); it != c.end(); /*empty*/)
{
if(IsBad(*it))
it = c.erase(it)
else
it++;
}
map
for(.. it = m.begin(); it != m.end(); /*empty*/)
{
if(IsBadKey(it->first))
{
it_del = it++;
m.erase(it_del);
}
else
it++;
}
C++ Standard Library: A Tutorial and Reference
mem_fun, mem_fun_ref, ptr_fun
class Number
{
private:
int _val;
public:
Number(int n): _val(n) {}
int Value() const { return _val; }
void mem_print() const
{
cout << _val << endl;
}
bool IsGreaterThan6()
{
return _val > 6;
}
};
void global_print(const Number &x)
{
cout << x.Value() << endl;
}
.......
.......
.......
vector<Number> vn;
vector<Number*> vpn;
for(int i = 0; i < 10; i++)
{
vn.push_back(Number(i));
vpn.push_back(new Number(i));
}
cout << "ordinary functions" << endl;
for_each(vn.begin(), vn.end(), ptr_fun(global_print));
//the same as : for_each(vn.begin(), vn.end(), global_print);
cout << "mem_fun_ref" << endl;
for_each(vn.begin(), vn.end(), mem_fun_ref(&Number::mem_print));
cout << "mem_fun" << endl;
for_each(vpn.begin(), vpn.end(), mem_fun(&Number::mem_print));
for(int i = 0; i < 10; i++)
delete vpn[i];
reverse iterator
// v1 = 0, 1,2, ... 9
vector<int>::iterator pos5 = find(v1.begin(), v1.end(), 5);
cout << *pos5 << endl; // 5
// convert normal iterator to reverse iterator, but value change!!!!!
vector<int>::reverse_iterator rp(pos5);
cout << *rp << endl; // 4 !!!!!!!!!
// convert reverse_iterator to normal iterator
assert(pos5 == rp.base());
// convert begin() to reverse_iterator is causing ERROR
//vector<int>::reverse_iterator rpos(v1.begin()) // RUNTIME ERROR!!!!
vector<int>::reverse_iterator r2(v1.begin()+2);
vector<int>::reverse_iterator r6(v1.begin()+6);
// correct !!
copy(r6, r2, ostream_iterator<int>(cout, ",")); cout << endl;
// ERROR!!1
//copy(r2, r6, ostream_iterator<int>(cout, ",")); cout << endl;
// construct a vector from stringstream
stringstream ss("0 1 2 3 4 5");
vector<int> v1;
copy((istream_iterator<int>(ss)),istream_iterator<int>(), back_inserter(v1));
bool IsEven_Function(int n)
{
return n % 2 == 0;
}
//function pointer V.S. function object
l Functor can hold state, while free function can’t
struct IsEven_Functor : public unary_function<int, bool>
{
bool operator()(int value) const
{
return value % 2 == 0;
}
};
// function pointer
remove_copy_if(v1.begin(), v1.end(), back_inserter(res), not1(ptr_fun(IsEven_Function)));
// functor, IsEven_Functor need to derived from unary_function to support not1(), and operator() should be const
remove_copy_if(v1.begin(), v1.end(), back_inserter(res), not1(IsEven_Functor()));
// multimap as dictionary
multimap<string, string> dict;
dict.insert(make_pair("Fruit", "Apple"));
dict.insert(make_pair("Fruit", "Pear"));
dict.insert(make_pair("Fruit", "Orange"));
dict.insert(make_pair("Animal", "Cat"));
dict.insert(make_pair("Animal", "Dog"));
dict.insert(make_pair("Animal", "Pig"));
dict.insert(make_pair("Animal", "Cow"));
string category("Fruit");
cout << category << endl;
for(multimap<string, string>::iterator it = dict.lower_bound(category);
it != dict.upper_bound(category); ++it)
{
cout << "/t" << it->second << endl;
}
// - pass function object by reference
//insert values from 1 to 4
//so that it will continue with 5
generate_n<back_insert_iterator<list<int> >,
int, IntSequence&>(back_inserter(coll), //start
4, //number of elements
seq); //generates values
query the state of your function object by checking the return value of for_each().
predefined function objects
Expression | Effect |
negate< type >() | - param |
plus< type >() | param1 + param2 |
minus< type >() | param 1 - param2 |
multiplies< type >() [4] | param1 * param2 |
divides< type >() | param1 / param2 |
modulus < type >() | param1 % param2 |
equal_to< type >() | param1 == param2 |
not_equal_to< type >() | param1 ! = param2 |
less< type >() | param1 < param2 |
greater< type >() | param1 > param2 |
less_equal< type >() | param1 <= param2 |
greater_equal< type >() | param1 >= param2 |
logical_not< type >() | ! param |
logical_and< type >() | param1 && param2 |
logical_or< type > () | param1 | | param2 |
predefined function adapters
Expression | Effect |
bind1st (op,value) | op(value,param) |
bind2nd (op, value) | op(param,value) |
not 1 (op) | !op(param) |
not2 (op) | !op(param1 ,param2) |
predefined function adapters for member functions
Expression | Effect |
mem_fun_ref (op) | Calls op() as a constant member function for an object |
mem_fun (op) | Calls op() as a constant member function for an object |
Function Adapters for Oridnary Functions
Expression | Effect |
ptr_fun (op) | *op(param) |
| *op(param1 ,param2) |