Notes on C++

links and resources and sparkles

 

iostream_iterator explain - for especially C programmer.

     istream_iterator<int> in_iter(cin); // read ints from cin
     istream_iterator<int> eof; // istream "end" iterator
     // read until end of file, storing what was read in vec
     while (in_iter != eof)
             // increment advances the stream to the next value
             // dereference reads next value from the istream
             vec.push_back(*in_iter++);

 Istream_iterator is an object, which has following features:

  •  It has 2 private members, one is T, the other is istream*.
  •  when ++(), it reads, invokes *istream>>T; when *(), it returns value of T.

 So it's just a wrapper for the operation and make code looks simple and same style.


     // write one string per line to the standard output
     ostream_iterator<string> out_iter(cout, "\n");
     // read strings from standard input and the end iterator
     istream_iterator<string> in_iter(cin), eof;
     // read until eof and write what was read to the standard output
     while (in_iter != eof)
         // write value of in_iter to standard output
         // and then increment the iterator to get the next value from cin
        *out_iter++ = *in_iter++;

  Ostream_iterator is an object, which has following features:

  •    It has 2 private members, one is delimit, usually char*, the other is ostream*.
  •    when ++(), it just return himself. when =(), it do *ostream >> T and >> delilim if has.

   So It is a wrapper too. C++ is not power C, but a wrapper of C. c++ in C is just operation which done by the CPU. c++ in C++ is a function which may do a lot of callings behind and because of this, c in C++ is not just a variable, it has upgrade to an object. so it has the C face(*out++=*in++) but has more meaning. From this point, please think of ()(functor), =, if (c), [] etc.  

 

my_cin - for debug in cygwin, just type "quit" to exit inputting

 class my_cin {
 std::istream & ii;
 bool ok;
 public:
    my_cin() : ii(std::cin), ok(1) {}
    my_cin(std::istream & is): ii(is), ok(1) {}
    std::istream& get(){return ii;}
    void stop(){ok=0;}
    bool end(std::string& s) {return s == "quit";}
    void clear() {ok=1;}
    operator bool() {return ok;}
};

template <class T>
my_cin& operator>> (my_cin& in, T& t)
{
 in.clear();
 in.get() >> t;
 if(in.end(t))in.stop();
 return in;
}

Using my_cin where cin is.  

Temporary Variable in C++ 
A another version of C++ Primer 4nd Codes Chapter 1.5   

In that chapter, we meet a program that till as a beginner we cannot write out the defination for Sales_item. Anywang without looking for the author's we can create our own. Just need some courage. but that may give you more to learn and see from the normal road. 

we just see a simple program, we will discuss line by line:

 1   #include <iostream>
 2 >> #include "Sales_item.h"
    << #include "Sales_item_v1.h"

   The only thing we can do this line is that we replace the 2 line with <<.  then we must work out what's will be in Sales_item_v1.h . 
 3   int main()
 4  {
 5     Sales_item book;
 6      // read ISBN, number of copies sold, and sales price
 7      std::cin >> book;
 8      // write ISBN, number of copies sold, total revenue, and average price
 9      std::cout << book << std::endl;
 10     return 0;
 11 }

In Sales_item_v1.h. .

#include <string>
class Sales_item {
 public:
     Sales_item(){};
     Sales_item(const Sales_item& rhs){};
     ~Sales_item(){};
private:
     std::string name;
     int count;
     float price;
};

the upper define can make the 5 line happy, ok we meet the 1st challenge: how to define << and >> operator.  please see Effective C++ to find the answer( Rules 19). we need a friend glocal functions. OK, let 's go:

 1. add declaration at head

 #include <iostream>

  2. in class defination, public section , add

 friend std::istream& operator>> (std::istream &in, Sales_item &si);
 friend std::ostream& operator<< (std::ostream &out, Sales_item &so);

  3. outside the class, add 2 global functions:

std::istream& operator >> (std::istream &in, Sales_item &si)
{
     in >> si.name >> si.count >> si.price;
     return in;
}
std::ostream& operator << (std::ostream &out, Sales_item &so)
{
     out << " " << so.name << " " << so.count << " " << so.price;
     return out;
}

 that's OK, so we continue, we meet

     #include <iostream>
     #include "Sales_item.h"   ---> remeber to change this line to your new header?
     int main()
     {
        Sales_item item1, item2;
        std::cin >> item1 >> item2;   // read a pair of transactions
        std::cout << item1 + item2 << std::endl; // print their sum
        return 0;
     }

 
  Oh, we need operator +, after we added to. (about operator +, go Effective C++)

  1. friend global functions inside class
 
friend const Sales_item operator+ (const Sales_item &lhs, const Sales_item &rhs);

  2. define global funtions outside class

const Sales_item operator+(const Sales_item &lhs, const Sales_item &rhs)
{
    if (lhs.same_isbn(rhs))
        return Sales_item(lhs.name, lhs.count+rhs.count, \
        lhs.count*lhs.price+rhs.count*rhs.price);
}

  3. we need a number function same_isbn() and copy-contructor Sales_item(string, int, float), ok, here we go

 Sales_item(const std::string &nm, int cn, float pr)
 { this->name = nm;this->count = cn;this->price = pr;};
 bool same_isbn(const Sales_item &rhs) const
 { return this->name == rhs.name;}

 just compile. anything ok ? no

1.5.cpp:17: error: no match for 'operator<<' in 'std::cout << operator+(const Sales_item&, const Sales_item&)(((const Sales_item&)((const Sales_item*)(&item2))))'

that is the error msg in my WinXp+Cygwin, something wrong? yes. the answer is temporary variable, the function before can do with normal variable cause it can be reference, but temporary? no! so ok, let ADD a another function which can deal with it. 

std::ostream& operator << (std::ostream &out, Sales_item so)
{
     out << " " << so.name << " " << so.count << " " << so.price;
     return out;
}
  it is ok, but when you go to the first program, it run another error.

1.5.cpp:16: error: ambiguous overload for 'operator<<' in 'std::cout << item3'


  the right solution is adding "const " in << operator:

 friend std::ostream& operator<< (std::ostream &out, const Sales_item &so);

  because temporary variable is "const sometype temp", this is also desribed in Effective C++ M15.

  Source code Download