C++マニアック

面白倉庫,Funny Storage

面白倉庫です。

ナオ : このページって何?
店主 : 何でしょうね、これは。

  1. Nest
  2. Mutate
  3. ちょっと、まぎらわしい
  4. Max
  5. C++ 関連本

Nest ページの先頭へ

これってネストかな。木かも。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;
}

Mutate ページの先頭へ

これって、ミューテートというより、単なるキャストか。コンテキストを一応利用できるってことだ。

#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;
}

ナオ : 変だって言われない?
店主 : 言われないなァ。ほぼ、誰も理解しないみたいなんだ。

Max ページの先頭へ

三個の数 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;
}

ナオ : 最初の () は、コンストラクタ呼び出しで、二番目からは関数呼び出しの () 演算子なわけネ。これって () の悪用?
店主 : ばれたか。