ストラウストラップのプログラミング入門(34) 19章ドリル(続)

ストラウストラップのプログラミング入門』を読む。19章ドリルの続きで、完結です。

前回はドリル12〜14の意図を掴みかねていましたが、faith_and_braveさんに頂いたコメントを参考に、read_val関数を下記のように使う問題だと考えることにしました。

int main()
{
	S<int> si;
	read_val(si);
	
	S<char> sc;
	read_val(sc);
	
	S<double> sd;
	read_val(sd);
	
	cout << "input vector<int> { x , y , z }: ";
	S< vector<int> > sv;
	read_val(sv);
	cout << sv.get() << endl;
}

read_val関数を使って、S型を特殊化したS、S、S、S< vector >型を統一された方法で読み込みます。

以下は、全体です。本文(ドリル14)の示唆どおり、vector用のoperator>>とoperator<<を定義しました。

#include "../../std_lib_facilities.h"

template<class T>
struct S
{
	S(): val(T()) { }
	S(T t): val(T(t)) { }

	const T& get() const;
	T& get();
	void set(T t);

	T& operator=(const T&);
private:
	T val;
};

// drill(14)
template<class T>
istream& operator>>(istream& is, vector<T>& v){
	T val1, val2, val3;
	char co, cc, comma;
	is >> co >> val1 >> comma >> val2 >> comma >> val3 >> cc;
	if(!is){ /* cout << "error!!!" << endl; */ return is; }
	if(co != '{' || cc != '}' || comma != ','){
		is.clear(ios_base::failbit);
		return is;
	}
	v.push_back(val1);
	v.push_back(val2);
	v.push_back(val3);
	return is;
}

// drill(14)
template<class T>
ostream& operator<<(ostream& os, vector<T>& v){
	return os <<  "{ " << v[0] << " , " << v[1] << " , " << v[2] << " }";
}

// drill(12)
template<class T>
istream& operator>>(istream& is, S<T>& v){
	T tmp;
	is >> tmp;
	if(!is){ return is; }
	v = S<T>(tmp);
	return is;
}

// drill(12)
template<class T>
void read_val(T& v){
	T tmp;
	if(cin >> tmp){
		v = tmp;
	}
}

template<class T>
const T& S<T>::get() const{
	return val;
}

template<class T> T& S<T>::get(){
	return val;
}

template<class T> void S<T>::set(T t) {
	val = t; 
}

template<class T> 
T& S<T>::operator=(const T& t){
	if(this == &t) { return *this; }	// 自己代入
	T tmp = new T();
	tmp = t;
	delete val;
	val = t;
	return *this;
}

int main()
{
	cout << "input int value: ";
	S<int> si;
	read_val(si);
	cout << si.get() << endl;
	
	cout << "input char value: ";
	S<char> sc;
	read_val(sc);
	cout << sc.get() << endl;
	
	cout << "input double value: ";
	S<double> sd;
	read_val(sd);
	cout << sd.get() << endl;
	
	cout << "input vector<int> { x , y , z }: ";
	S< vector<int> > sv;
	read_val(sv);
	cout << sv.get() << endl;

	keep_window_open();
}

ひとまず、これで19章は終わりということで。

おまけ

演算子オーバーロードについて調べていて読んだページ。

# 19章のドリルでは、上記のページが解説する内容より、もっと簡単なことを問われていたので、直接参考にしたわけではありませんが、そのうち読み直すことがあるかもしれないので、貼っておきます。