月別アーカイブ: 2008年3月

STL の本

そういえば去年財布を盗まれてクレカの再発行をしたのを忘れていた。
SAKURA から「引き落とし不能」のメールが…やっちまったい!
再発行すると番号が変わっちゃうのよ。

たった今オンラインで振り込んだけどもし止められたらゴメン。
多分今年中に移転するような気がするんですけど、今は決定していないけど。
といっても急に無くなったら行方不明だしマイッタわ。

つーことで久々に本の紹介。

今コレを読んでいます。
今度は STL かい…と呆れないでくれ。

この本は、、、、、恐ろしく解りにくい!

とにかく難しい、といっても STL 自体が解りにくいのであるが。
だいたい反復子って名前はなんじゃい、もっとイイ翻訳は無かったのか?

知識がある人が本を書くと、ついうっかり深い所まで説明しようとする。
だから難しさが倍増して投げ出したくなってしまう、その典型な文章。

でもだから深い所まで書いているので今はとても嬉しい。
素晴らしい内容の本です、人間って調子がいい生物だなと。

STL は一端使い方を覚えてしまえば楽ちんなのはポインタと同じだね。
てゆーか std::vector だけなら反復子は完全にポインタと同じだと。
それが解るようになる本という事ならとても勧められない文章である。
逆に解っている人であれば買いです、自分でコンテナを作る方法まで解説してる。

プログラミング本を買う決めてがなんとなく解った。
とにかく文字ばっかで画像がほとんど無い本を選びましょう。
今は全然解読できなくても後で役に立つ場合がある。

Intellisense の更新

全然完璧じゃなかった…
コレじゃ Add で同一キーが混在する場合があるやないの。

void CPairList::Add(LPCWSTR szKey, LPCWSTR szValue)
{
    vec_t::iterator it = m_vec.begin();
    vec_t::iterator itend = m_vec.end();
    for (; it != itend; it++)
    {
        if ( (*it).first == szKey)
        {
            (*it).second = szValue;
            return;
        }
    }
    m_vec.push_back(Pair(szKey, szValue));
}

でいいかな。
つーか wstring を二回も typedef する必要なんて無いわな。
キリがないので続きは多分今週末に更新する Cinema のソースで。

ところで。

Intellisense の更新は手動でやれないのかなぁ?
一度作ったクラスにメソッドを追加していくと認識されない場合が多い。

知らない人のために一応書くとコード補完機能のことである。
Ctrl+Space や先頭に :: を打つとグローバルな関数や変数を補完してくれたりとか
ドットや -> を打つと全自動でクラスメソッドを一覧表示してくれてありがたい。

コレがメソッド追加で自動反映されるまでの時間がチト長いのよ。
酷いときにはいつまでたっても反映されないということもあるんです。
古い VC++ はよく知らないけどデルヒャァ5は即時反映だったので気になるわ。

普通に手書きすればコンパイルは通るから Intellisense だけの問題だね。
コレでは Visual Studio のエディタを使っている意味はまったく無いんだが…
便利だからと頼りまくってコーディングというのもどうかと思うけど。

なんとかならんかと検索しまくったがみんなやっぱりそんな感じなのね。

どうやらソリューションのディレクトリにある .nbc がその実体らしい。
一端終了後にこのファイルを削除して再起動で作り直しリセットする。
やっぱりこの方法しかないのかな?メンドクセ。

CPairListClass

完璧だ。
Classes.h,Classes.cpp として

#pragma once   

class CPairList 
{ 
private: 
??? typedef std::wstring m_a; 
??? typedef std::wstring m_b; 
??? typedef std::pair<m_a, m_b> Pair; 
??? typedef std::vector<Pair> vec_t; 
??? vec_t m_vec; 
public: 
??? void Add(LPCWSTR szKey, LPCWSTR szValue); 
??? void Remove(LPCWSTR szKey); 
??? std::wstring operator[](std::wstring szKey); 
??? std::wstring GetValue(int i); 
??? std::wstring GetKey(int i); 
??? int Count(); 
};
//??? TODO: "StdAfx.h" #include <vector>    

#include "StdAfx.h"
#include "Classes.h"   

/* 
 *??? CPairListClass 
 */   

void CPairList::Add(LPCWSTR szKey, LPCWSTR szValue) 
{ 
??? m_vec.push_back(Pair(szKey, szValue)); 
}   

void CPairList::Remove(LPCWSTR szKey) 
{ 
??? vec_t::iterator it = m_vec.begin(); 
??? vec_t::iterator itend = m_vec.end(); 
??? for (; it != itend; it++)? 
??  {? 
?????? if ( (*it).first == szKey)? 
?????? {? 
?????????? m_vec.erase(it); 
?????????? break;? 
?????? } 
??? } 
}   

std::wstring CPairList::operator[](std::wstring szKey) 
{ 
??? std::wstring result; 
??? vec_t::iterator it = m_vec.begin(); 
??? vec_t::iterator itend = m_vec.end(); 
??? for (; it != itend; it++)? 
 ?? {? 
?????? if ( (*it).first == szKey)? 
?????? {? 
?????????? result = (*it).second; 
?????????? break; 
??????? } 
??  } 
??? return result; 
}   

int CPairList::Count() 
{ 
??? return m_vec.size(); 
}   

std::wstring CPairList::GetValue(int i) 
{ 
??? return m_vec[i].second; 
}   

std::wstring CPairList::GetKey(int i)  

{ 
??? return m_vec[i].first; 
}

と定義しておいて

CPairList aList; 
aList.Add(L"おまえ", L"あほ");  

wstring ws = aList[L"おまえ"];

な感じで順番は保持されたままの連想配列もどきの完成、STL 恐るべし。
でも現在 ini 保存に std::map を使っているのでココでソートされてしまう…
こっちも変更しなきゃ、あぁ先は長い。

しかしワシもいつのまにかこんなコードが普通に書けるようになった。

思えば二年前に唐突にデルヒャァから C++ に乗り換えして
「やっぱりポインタがワカンネェ!意味は解るけど使い方が全然ワカンネェ!」
だったのにね。

std::pair<_Ty1, _Ty2>

何故気がつかなかったのだ…

std::pair<_Ty1, _Ty2>

のテンプレートに wstring を両方突っ込んで vector コンテナって方法があった。
使うときには first メンバをキーにして取り出せばイイだけだ。
この方法なら設定の並び順は保持可能かつ拡張時の並び順も問題無い!

でもやってみないとどうなるか解らないわな。

class CGesMap
{
private:
    typedef std::wstring m_a;
    typedef std::wstring m_b;
    typedef std::pair<m_a, m_b> Pair;
    typedef std::vector<Pair> vec;
    vec m_vec;
public:
    void SetGesture(LPCWSTR szGesture, LPCWSTR szValue);
    std::wstring GetValue(std::wstring szGesture);
    std::wstring GetValue(int i);
    std::wstring GetKey(int i);
    int Count();
};

こんな感じで明日色々やってみます。
今日も休日出勤で疲れているのでまた明日。

並び順

いいかげんにマウスジェスチャの設定を付けようと考えた。
まあ設定保存形式なんかは Y901 の時にやっていたのですぐ決まるわな。
実装部分だけなら連想配列を使って半日掛からず作れた。
wstring と int をペアで格納してと。

20080320.JPG

困ったぞ。
連想配列(つまり std::map)って勝手にソートしちゃうんだね。
検索効率を考えると「そりゃそうだ」なんですけど…

実はカスタマイズ部分は順番という概念を消したいのよね。

いわゆる配列や TList なんかを使うと整数という順番が決まる。
その整数という順番を利用してアクセスするのが普通、ココが落とし穴。
真ん中に何か追加しようとするとソレ以降の整数という順番が変わってしまう。
結果最後尾に追加しか方法が無くなって違和感のある列のできあがり。

と、Pallepoli のキーカスタマイズを拡張しようとしたときに困ったので。
一端順番を決めて作ってしまうと後での追加は最後尾にしかできないわけです。
後でどうにでも配置できるようにするには順番を使わないという方法しかない。

それなら連想配列だ!架空の順番を付け取り出し時に好きに並べればイイ!

とやってみたのですが…今度は全自動ソートという魔物がいた。
これではユーザーが設定で並べた順番さえ勝手にソートされてしまう。
インターフェイス部分を作ろうとしてガックリしてしまった。
開発者側の問題は解決するがこうなるか、凡庸させるにはキツイ。

あーあ、せっかくクラスを作ったのに、さてどうしよう。

又自分で最初から作るしかないっぽい。
2つの動的配列か vector を同期させて片方の値をキーと仮定させて…
ってエラくレスポンスの遅いリストになりそうな雰囲気だ…
まあ今時のパソコンならそれでもいいんじゃないかとか…