面白倉庫です。
ナオ : このページって何?
店主 : 何でしょうね、これは。
これってネストかな。木かも。map の応用ってことね。
#pragma warning(disable:4786) #include <map> #include <string> using namespace std; struct Nest : public map<string, Nest*> { Nest& operator [](const string& rstrName) { return (*this)[rstrName]; } }; int main() { Nest nest; nest["this"]["that"]["a"]["b"]["c"]; // って、アクセスできるってこと。 return 0; }
これって、ミューテートというより、単なるキャストか。コンテキストを一応利用できるってことだ。
#include <string> using namespace std; struct Mutate { operator int () { return 1 ; } operator string() { return "値は 1 だナ。"; } operator bool () { return true ; } // 嘘より、真実のほうが好きだ。 }; int main() { int iValue = Mutate(); // コンストラクタの呼び出しと int への変換 string strValue = Mutate(); // コンストラクタの呼び出しと string への変換 Mutate mutate; if (mutate) { /*...*/ } // if のコンテキストは bool なわけで。 return 0; }
コンストラクタとキャスト演算子と関数呼び出し演算子って、どれも () なんで、ちょっと書き方や使い方がまぎらわしいんですよネ。
#include <string> using namespace std; struct Maniac { Maniac () {} // これは、デフォルトコンストラクタだネ。 Maniac (const string& rstr) {} // これは、普通のコンストラクタだネ。 string operator ()(int iValue) { return "マニアック"; } // これは、関数呼び出し演算子だネ。 operator string() {} // これは、キャスト演算子だネ。 }; int main() { { // 普通の人は、こう使うのかなア。 Maniac maniac0; // デフォルトコンストラクタの呼び出し Maniac maniac1("マニアック"); // 普通のコンストラクタの呼び出し string str0 = maniac1(3); // 関数演算子の使用 string str1 = maniac1; // string へのキャスト } { // C++マニアックは、同じことをするのに、大抵は、こう使うネ。 Maniac& rmaniac0 = Maniac(); // 参照でオブジェクトを掴んでおくわけネ。 Maniac& rmaniac1 = Maniac("マニアック"); // これも同じ。 string str0 = Maniac("マニアック")(3); // その場でオブジェクトを作って使って捨てるわけネ。 string str1 = Maniac("マニアック"); // これも同じ。 // 参照で掴んでいるオブジェクトは、って言うと、 string str2 = rmaniac0(3); // 参照を介してオブジェクトを使うわけ。 string str3 = rmaniac1; // これも同じ。 } return 0; }
ナオ : 変だって言われない?
店主 : 言われないなァ。ほぼ、誰も理解しないみたいなんだ。
三個の数 a、b、c から最大のものを選ぶとき、max(a, max(b, c)) とか書くのは、ちょっと嫌ですよね。四個とか五個とかになると、発展性に乏しいと言いますか。
そこで、C++マニアック的には、こうなります。
template <class T_value> struct Max { T_value m_tv; Max(const T_value& tv) { m_tv = tv; } Max& operator()(const T_value& tv) { m_tv = m_tv > tv ? m_tv : tv; return *this; } operator T_value() { return m_tv; } }; int main() { // 一番大きな数は、どれだろう。 int iMax = Max<int>(3)(4)(5)(-2)(1); // 答えは、多分 5 でしょうね。 return 0; }
ナオ : 最初の () は、コンストラクタ呼び出しで、二番目からは関数呼び出しの () 演算子なわけネ。これって () の悪用?
店主 : ばれたか。