C++第3版 10章 練習問題解答

目次へ戻る

10.1

§10.2.2 のadd_year のミスは、§10.2.7 を見ればわかる通り、 存在しない年月日になる可能性がある点である。
§10.2.7 のエラーは、0年になる可能性があることと、 int の範囲を超えた時の対応がないことであろうか。 しかし、1番目の点は、年の読み出しを
int Date::year()const{return y-(y<=0);}
と直せば済む。(すなわち add_year は正しい) 2番目の問題も実際の利用には問題ないと思われる。 (あるいは、使用できる年の範囲を前提条件とすればよい。)
穿った見方をすれば次のようなことも考えられる。

10.2

ちょっとパス。

10.3

これもパス。

10.4

10.5

パス。

10.6

パス。

10.7

パス。

10.8

7.7参照のこと。

10.9

#include <iostream>
#include <list>
#include <set>
#include <algorithm>
using namespace std;

template <typename T>
struct Anyset : public set<T> {
    Anyset(){}
    Anyset(const list<T>& l){list<T>::iterator i;
        for (i=l.begin();i!=l.end();++i) insert(*i);}
    Anyset Union(const Anyset& a)const{list<T> r;
        set_union(begin(),end(),a.begin(),a.end(),
        back_inserter(r)); return r;}
    Anyset Intersect(const Anyset& a)const{list<T> r;
        set_intersection(begin(),end(),a.begin(),a.end(),
        back_inserter(r)); return r;}
    Anyset SymDiff(const Anyset& a)const{list<T> r;
        set_symmetric_difference(begin(),end(),a.begin(),a.end(),
        back_inserter(r)); return r;}
};
template <typename T>
ostream& operator<<(ostream& o,const Anyset<T>& a)
{
    Anyset<T>::iterator i;
    for (i=a.begin();i!=a.end();++i) o << *i << " ";
    return o;
}

struct Node {
    int id;
    Node(int i = 0) : id(i) {}
    operator int()const{return id;}
};

typedef Anyset<int> Intset;
typedef Anyset<Node> Nodeset;

int main()
{
    Intset  i,j;
    i.insert(7); i.insert(2); i.insert(3); i.insert(5);
    j.insert(2); j.insert(3); j.insert(1);
    cout << "Union     " << i.Union(j)     << endl;
    cout << "Intersect " << i.Intersect(j) << endl;
    cout << "SymDiff   " << i.SymDiff(j)   << endl;
    Nodeset  k,l;
    k.insert(7); k.insert(2); k.insert(3); k.insert(5);
    l.insert(2); l.insert(3); l.insert(1);
    cout << "Union     " << k.Union(l)     << endl;
    cout << "Intersect " << k.Intersect(l) << endl;
    cout << "SymDiff   " << k.SymDiff(l)   << endl;
}

10.10

10.9参照のこと。

10.11

6.18参照のこと。

10.12

パス。

10.13

パス。

10.14

6.18参照のこと。

10.15

main の前に以下を追加。
struct A {
//  A(){std::cout << "Initialize\n";}
//  ~A(){std::cout << "Clean_up\n";}
    A(){system("echo Initialize");}
    ~A(){system("echo Clean_up");}
} dmy;
本当は、コメントの様に書きたい所だが、そうすると Clean_up が出力されない。 呼出される時に既に、出力が切られているようだ。atexit とかを使ってもだめであった。 この例ではもちろん、OS で echo が使えないといけない。

10.16

パス。

10.17

実行順の依存を取り除くには、メンバを参照するのではなく、 関数からアクセスするようにすればよい。

10.18

パス。

10.19

#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <strstream>
using namespace std;

typedef map<string,vector<int> > MType;
MType MakeMap(istream& i,vector<string>& v)
{
    MType   r;
    string  s,t;
    int     l = 0;
    while (getline(i,s)) {
        ++l;
        istrstream is(s.c_str());
        while (is >> t) 
            if (find(v.begin(),v.end(),t) != v.end())
                r[t].push_back(l);
    }
    return r;
}

int main()
{
    vector<string>  v;
    v.push_back("const");
    v.push_back("cout");
    v.push_back("double");
    v.push_back("vector");
    MType m = MakeMap(cin,v);
    MType::iterator i;
    for (i=m.begin();i!=m.end();++i) if (i->second.size() >= 10) {
        vector<int>::iterator j;
        cout << i->first;
        for (j=i->second.begin();j!=i->second.end();++j)
            cout << " " << *j;
        cout << endl;
    }
}

10.20

問題の意味が良く分からないが、一応書いてみる。 (意味のつかみにくい問題がよくある。)
struct Value {
    enum Type {S,I};
    Type    t;
private:
    union {
        char*   s;
        int     i;
    };
public:
    Value(){t = S; s = 0;}
    char* GetS()const{assert(t == S); return s;}
    void SetS(char* s0){assert(t == S); s = s0;}
    int GetI()const{assert(t == I); return i;}
    void SetI(int i0){assert(t == I); i = i0;}
};
struct Entry {
    char*   name;
    Value   val;
};

前章目次次章