213 名前:デフォルトの名無しさん[sage] 投稿日:2008/01/26(土) 13:35:49 前に関ったプロジェクトは常にフル指定?でメソッドを呼び出すべし という規約があった 基底クラスのメソッドさえも Hoge::Foo:Base:Dosomething(); 多重継承を多用していたからという事情もあるんだけど 面倒だけど、安全ではあるほほー、fully qualifiedで関数を呼び出す規約ですか。そのプロジェクトでは、ハローワールドは次のようになるんですね。
2008-01-26
ばかげたコーディング規約
CSSを使った、即席の縦書きビューワ
2008-01-25
平家物語の読書の進捗
ブラック企業
ブラック会社に勤めてるんだが、もう俺は限界かもしれない
ブラック会社に勤めてるんだが、もう俺は限界かもしれない 2
第二部:ブラック会社に勤めてるんだが、もう俺は限界かもしれない
第三部:ブラック会社に勤めてるんだが、もう俺は限界かもしれない
第四部:ブラック会社に勤めてるんだが、もう俺は限界かもしれない
第五部:ブラック会社に勤めてるんだが、もう俺は限界かもしれない
完結:ブラック会社に勤めてるんだが、もう俺は限界かもしれない
コレはひどい。
で、そのシャチョーサンとやらは何をしているんだろ。
で、もうひとつ、
>マ男くん、今君は、この会社をやめたいって思ってるだろう。その気持ちが分からない事もない。
>だけど、やめた先に何があるだろう? よく考えてごらん。私は、今はやめるべきではないと思うよ。
なぜやめない? 別に仕事がプログラマである必要性がない。精神の向上? 馬鹿馬鹿しい。一トンの重りを背負ってフルマラソンするぐらい馬鹿馬鹿しい。
それでも、まだ自分もプログラマになる一抹の夢をあきらめていなかったりするわけだ。どこか、C++の文法にしか興味がない者を、雇う所はないかな。ないよな。仕事どうしよう。
テレビ業界のコモンセンスは理解できない
2008-01-24
日本の携帯は中国と同じレベルの言論統制が敷かれる事と相成りました。
2008-01-22
義務教育はよかった
平家物語 読書を進めて
2008-01-20
Boostのenable_ifについて
Boostには、enable_ifというメタ関数がある。このメタ関数の実装は、実はとても短い。とても短いので、分かりやすい。
template < bool B, class T = void > struct enable_if_c { typedef T type; } ; tempate < class T > struct enable_if_c< false, T > {} ; template < class Cond, class T = void > struct enable_if : public enable_if_c< Cond::value, T > {} ;
きわめてシンプルだ。なお、これの逆をする、disable_ifなるメタ関数もある。まず、語るよりも、例を示そうと思う。そのほうが分かりやすいだろう。
例えば、ある関数の呼び出しを、組み込みの整数型に限りたい場合は、どうすればいいだろう。C++では、関数のオーバーロードをサポートしている。
int f(int x) ; unsigned int f(unsigned int x) ; short f(short x) ; unsigned short f(unsinged short x) ; //以下略
何て面倒なんだろう。それぞれの関数ごとに、同じようなコードを何度も何度も書かなければならない。そこで、テンプレート関数というものがある。テンプレートを使えば、このような無駄な記述は省ける。
template < typaname T > T f(T x) { return x << 5 ; //ビット演算を使う。 }
これは、すばらしい。しかし、もしこの関数を整数型の呼び出しに限定したい場合は、どうすればいいのだろう。そこで、enable_ifが役に立つ。
template < typaname T > T f( T x, typename boost::enable_if< boost::is_arithmetic<T> >::type * = 0 ) { return x << 5 ; //ビット演算を使う。 }
enable_ifは、一つ目の型引数のメタ関数の戻り値が真の場合、二つ目の型引数を返す。もし偽であったならば、型は定義されない。しかし、C++の規格では、コンパイルエラーにはならない。なぜならば、C++にはSFINAE(Substitution Failure Is Not An Error)という規格がある。このため、単に関数が、Overload Resolutionの候補から外れるだけだ。ほかには、次のような使い方もある。
//戻り値の型として使う template < typaname T > typename boost::enable_if< boost::is_arithmetic<T>, T >::type f( T x ) { return x << 5 ; //ビット演算を使う。 } template < typename T, typename Enable = void > class Foo ; //整数型にだけ特殊化 template < typename T > class Foo< T, typename boost::enable_if< boost::is_arithmetic<T> >::type > ;
しかし、依然としてis_arithmeticのようなメタ関数を書かなければならないことに変わりはないし、何の利点があるのか、と思うかもしれない。その場合は、STLのvectorを実装してみるといい。
STLのvectorには、いくつかのコンストラクタがあるが、そのうち、イテレータを引数に取るコンストラクタと、要素数を初期値を引数に取るコンストラクタがある。
void f(int * first, int * last) { std::vector<:int> v(first, last) ; // vectorはイテレータで初期化される std::vector<:int> v(10, 123) ; // vectorは要素数10で、初期値が123 }
とても便利だ。さて、早速実装しよう。話を簡単にするために、詳細な実装は省き、コンストラクタだけを定義してみる。
template < typename T > class vector { public : vector( unsigned int n, T val = T() ) { T x = val ; } template < typename Iterator > vector( Iterator first, Iterator last ) { T x = *first ; } } ;
さて、さっそくテストしてみよう。ところが、次のコードがコンパイルできないという文句が、大量に殺到して、君のgmailアカウントが容量オーバーになってしまった。
std::vector<int> v(10, 123) ;
なぜか、イテレータを引数にとるコンストラクタが呼ばれてしまう。この理由を説明するには、Overload Resolutionの規格を説明しなければならない。それを説明しだすと長いので、ここでは説明しないが、とにかく、オーバーロードの解決は、テンプレートの実体化が終わった後に行われるということだ。この場合、次の二つの候補がある。
//イテレータ vector(int first, int last) ; //要素数と初期値 vector(unsigned int n, int val) ;
なぜこうなるかというと、10とか、123などといったリテラルの型は、int型だからだ。さて、いったいどちらの関数が呼ばれるのが、自然だろうか。要素数と初期値をとるコンストラクタは、int型からunsigned int型への変換が必要だ。すると、変換せずとも呼べるほうがよい。そこで、イテレータ版のコンストラクタが呼び出される。めでたしめでたし。
そう、悪いのはクラスを書いた俺じゃない。ライブラリのユーザの、C++の規格について、理解が浅いのが原因だ。次のように呼び出していれば、イテレータの方は呼び出されないのだ。
std::vector<int> v(10u, 123) ;
注意深く観ると、一つ目の引数の後ろに、uがついている。これは、リテラルがunsigned型であることを明示している。テンプレート関数と、普通の関数が重なった場合、普通の関数が優先されるルールがあるので、これで望みの動作が得られる。ユーザは文句を言う前に、ちゃんと型を考えるべきだったのだ。どっとはらい。
と、ここで話は終わらない。相変わらず、君の二つ目のgmailアカウントは容量オーバーのままだ。ここで必要とされているのは、なんとかテンプレート関数が、Overload Resolutionの候補に挙がるのを、制限する方法だ。ユーザがいちいち、引数の型がsignedかunsignedか考えなければならないのは、苦痛極まりない。そこでdisable_ifの出番だ。
template < typename T > class vector { public : vector( unsigned int n, T val = T() ) { T x = val ; } template < typename Iterator > vector( Iterator first, Iterator last , boost::disable_if< boost::is_integral<Iterator> >::type * = 0) { T x = *first ; } } ;
これで、望みどおりの動作が得られる。ユーザは何もする必要がない。いちごさけた
2008-01-19
平曲
平曲のCDってどこかに売っているのかな。ググって見た限りでは、大型書店にありそうな気がするが。しかし、いま、最初から最後まで、そらで語れる琵琶法師はいるのだろうか。
関係ないが、今年に入ってから、よいと思った音楽
これは、どうも数年前の歌らしい。こんな歌を知らなかったとは。
ひぐらしのOPの歌らしいが、コレはすばらしい。なんだか泣き出しそうな歌だ。
It's A Burning Desire! It's Burning Me
この同志は革命的に歌がうまい。我らと思想を同じくする同胞は観るべきだ。
たまたま、いま平家物語を読んでいるので、ツボにはまった。それだけの話。
2008-01-18
BoostのSandBoxを探検する
2008-01-16
BoostのMPLへのいざない part 2
MPLの続きを書く前に問題がひとつ
警察は失業率を基にして刑法犯認知件数にノルマを設定している
BoostのMPLへのいざない part 1
2008-01-15
引用権 正当な権利の侵害
C++で天啓を得る
もっとC++で遊ぶことにした
2008-01-14
C++で遊ぶことにした
2008-01-13
VC9のよく分からない致命的なエラー
2008-01-10
Es というゲーム
http://arthearts.net/9th-night/Es/ から体験版を落とすことができる。 公式サイトでは、どのようなゲームかさっぱり分からないが、とても面白いゲームだ。この動画を見れば、その面白さが実感できるはずだ。
これは製品版が待ち遠しい。しかし、d3dx9_33.dllが同梱されている。やれやれ、同人ゲームの世界ってどこも変わらないな。
どうすりゃいいんだ。
トレーサビリティ(笑)
私共、水穂米穀は、お客様の立場に立った日本一の『米屋』=『Rice Shop』を目指しております。 また、米穀店として販売量や売上高等での企業イメージよりも、お客様へ【商品情報を開示】することで、食品としての【安全性】を知っていただくこと、いわゆる【商品イメージ】が大切だと考えました。 「お米」は人の原動力であり、日々の食卓に無くてはならない食材です。 お客様に「食事を楽しく」また「安心」に食べていただく為にも、「お米」に関する豆知識や商品詳細情報(トレサビリティー=精米日毎に生産地・生産者等の情報を開示)を随時公開・更新をしてまいります。粗悪米を「ひとめぼれ」に偽装、海自に30トン納入 ほほー、証明書を偽装することがトレーサビリティですか。お主もワルよのう。
2008-01-09
今日は実に暖かい日であった
2008-01-07
コンピュータうそつかない
2008-01-05
煙草を吸う奴らはどうしようもない
2008-01-04
ゲームのプレイ動画は映画か
2008-01-03
Railsのコミュニティはゲットーだ
2008-01-02
VFRはいまだ浸透せず
動画というのは、言うなれば画像の連続だ。静止画が連続していることにより、動きとして見えるわけだ。ここでもし、動画のある区間で、動きがない場合、フレームを連続させず、止めていても、人間の目には分からないはずだ。動きがほとんどない場合は、フレームレートを落としても、人間の目には分からない。逆に、動きが激しい場合、この場合は、フレームレートをあげたほうがいいはずだ。
どのような状況にもかかわらず、フレームレートを一定に保つことを、CFR(Constant Frame Rate)といい、フレームレートが可変であることを、VFR(Variable Frame Rate)という。
VFRは理にかなっていて、すばらしいのだが、世の中はいまだにCFRが多い。理由は、VFRにまともに対応しているソフトウェアが少ないからだ。
動画をエンコードする際、入力は既にVFRになっているとしよう。ここで言うVFRとは、ある区間がCFRの30fpsで、ある区間がCFRの60fpsというものではなく、本当に1フレームごとに時間が違っているような、VFR動画のことだ。
H.264にエンコードする場合の、現状はどうだろう。
x264は、動画ストリームをmp4やmkvコンテナに入れて吐くことができるが、VFRにはならない(非公式のパッチはあるにしても)。エンコーダ自体がVFRを取り扱ってくれるのが、理想なのだが、まず現状は、そう恵まれていない。
では、timecodeを出力して、別途、動画ストリームをコンテナにmuxするときに、フレームレートを設定するというのはどうか。mkvコンテナであれば、この方法はとてもうまくいく。最も有名なmkvmergeが、実に分かりやすいフォーマットのtimecodeを受け付けてくれるからだ。しかし、mp4コンテナは恵まれていない。最も有名なmp4boxが、mkvmergeのように分かりやすいtimecodeの入力をサポートしていないからだ。世の中には、現状を打開すべく、tc2mp4なるPerlスクリプトがある。しかし、これは私の理想とするところではない。このスクリプトが何をしているかというと、mkvmergeのtimecodeファイルを、NHMLに変換しているのだ。なぜこんな不便なステップを踏まなければならないのか。
また、AviSynthがVFRに対応していないので、x264にVFRを入力するのも一苦労する。おそらく現状では、フレームを重複させるなどして、一旦CFRに変換し、Decombプラグインで重複するフレームを脱落させてVFRにし(このプラグインはmkvmergeのtimecodeを吐いてくれる) 上記のステップを踏む形になるだろう。なんて無駄が多いのだ。
結局、VFRなH.264のmp4を作る場合、
- DirectShowSourceで、VFRを、フレームを重複させることでCFRにする。
- Decombというプラグインで重複フレームを削除、mkvmerge用のtimecodeを出力する。
- AviSynthの出力を、x264でエンコード。
- tc2mp4という、Perlスクリプトを使い、timecodeをNHMLに変換して、mp4boxで適用する。
どう考えても不便極まりない。
さらに絶望的なことに、こうまでしてVFRにしても、劇的な画質向上、ビットレート削減など得られないということだ。
第一、動画を、WUXGA(1920x1200)などの高解像度に拡大してコマ送りで再生し、
「おお、このうp主のエンコードは流石だな。職人芸を感じるぜ」
とか言いつつニヤニヤする奴など、いったい何人いるのだろう。やれやれ、しばらくはVFRをCFRに変換してエンコードしたほうが、楽そうだ。