トップページtech
985コメント328KB

Generic Programming with C++ Template

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
C++ による Generic Programming の話をしよう。

参考図書:
Modern C++ Design
Andrei Alexandrescu, Addison-Wesley, ISBN:0-201-70431-5
(訳書: ピアソン・エデュケーション, ISBN:4-89471-435-3)
http://cseng.aw.com/book/0,,0201704315,00.html

Generic Programming - STL による汎用プログラミング
Matthew H. Austern, ASCII, ISBN:4-7561-3441-6

関連スレッド:
C++相談室 Part3
http://pc.2ch.net/test/read.cgi/tech/1003832761/

STL スレッド
http://pc.2ch.net/test/read.cgi/tech/1004287394/
0334デフォルトの名無しさんNGNG
C++ Builderってバージョンあがってもう少し使えるようになるかと思ったら
テンプレート周辺にバグがあるんでしょ?がっかり。
しっかりしてくれよ、Borland。期待してるんだから。Pascal以外の言語もがんばってくれよ。
0335デフォルトの名無しさんNGNG
>>334
えっ?初耳。ソースはどこかにありますか?教えて下さい
0336デフォルトの名無しさんNGNG
>>333
struct pr : public std::binary_function< string, string, bool>{
bool operator()(const string& x, const string& y)const{
return search(x.begin(), x.end(), y.begin(), y.end()) != x.end();
}
};

vector<string> articles;
・・・

articles.erase(remove_if(articles.begin(), articles.end(), bind2nd(pr(), "ぢ")), articles.end());
articles.erase(remove_if(articles.begin(), articles.end(), bind2nd(pr(), "ちう")), articles.end());
0337デフォルトの名無しさんNGNG
いっそのこと、
articles.erase(remove_if(articles.begin(), articles.end(), bind2nd(pr(), "FUKUDA Fumiki")), articles.end());
で。

0338デフォルトの名無しさんNGNG
>>334
えっ?猫耳。
0339デフォルトの名無しさんNGNG
>>338
えっ?愛猫。
0340デフォルトの名無しさんNGNG
>338-339
つまんねーよきみら
0341デフォルトの名無しさんNGNG
http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html

すごい!!
0342デフォルトの名無しさんNGNG
VC7へぼい・・

template<class T> void swap(T& x, T& y) {}
template<class T> void swap(vector<T>& x, vector<T>& y) {}

これコンパイル通らないんだよね・・
プログラミング言語C++ではこういう書き方してるのに。
0343デフォルトの名無しさんNGNG
>>342
using namespace std; を外して、std::vector にしてごらん。
0344デフォルトの名無しさんNGNG
あげげ
0345デフォルトの名無しさんNGNG
おまえらに質問。

最近関数オブジェクトがおもしろくてしょうがないんだけど、
引数がいっぱいあるメンバ関数をもつクラス T があるとして、
std::vector<T> t(100);
std::for_each(t.begin(), t.end(), &T:func);
みたいなのを引数渡ししつつぐるぐるやる方法はないかな。
mem_funcだとうまく引数が渡せないので、引数をなんとかする
関数オブジェクトをいっこつくってぐるぐるするしかないと思うんだけど、
いざコードを書こうとするとかっこわるくていかんのです。

0346デフォルトの名無しさんNGNG
どっちかというとSTLスレで聞くべきだった。
sage鬱

0347デフォルトの名無しさんNGNG
>>345
boost::bindとboost::mem_funとかで出来るんじゃないか?
0348デフォルトの名無しさんNGNG
>>347
たとえば引数が三つあるメンバ関数を考えたとき、
すべての引数に値を渡せるかな?

0349デフォルトの名無しさんNGNG
>>348
3つのうち2つが固定なら出来るんじゃないか?
0350デフォルトの名無しさんNGNG
>>349
ふむ。ちと試してみるよ。
ありがとん

0351デフォルトの名無しさんNGNG
>>343

template<T> void swap(T& x, T& y) {}
template<T> void swap(Class<T>& x, Class<T>& y) {}

2個のオーバーロード関数があいまいで最適な変換ができません。

STLソースではこうなってる模様
template<class T> Class {
public:
friend void swap(Class& x, Class& y) {}
};

でもこれでは既に他の名前空間にあるswapを特殊化できない罠。
なんかおかしくない?
おかしいのは漏れ?
0352デフォルトの名無しさんNGNG
>>351
たぶん、キミがおかしい。
VC7 のことはよくわからんけど、ふつう swap は <algorithm> の中で
次のように定義されているはず:
namespace std{
template<class T> inline void swap(T& x, T& y) { … }
}
で、何か標準ヘッダーをインクルードして、using namespace std;
してるでしょ? それで、1行目の swap とバッティングしてるんだと
思うけど。
ちなみに、2行目の swap は関係ない。それを外してもエラーが出るん
じゃない?
0353デフォルトの名無しさんNGNG
お手軽だからって
using namespace std はやめよーよ。
0354デフォルトの名無しさんNGNG
>>352
例が悪かった・・
swapじゃなくてなんでもいいです。
とにかくテンプレート関数をクラステンプレートで特殊化しようとすると
特殊化優先順位で弾かれる。
名前空間とは関係ない問題です。(これが後々関係してくるが)
0355デフォルトの名無しさんNGNG
具体例を書くよ

template<class T> class Class {};
template<class T> void func(T& x, T& y) {}
template<class T> void func(Class<T>& x, Class<T>& y) {}

void main() {
Class<int> x, y;
func(x, y);
}

error C2667: 'func' : 2 個のオーバーロード関数があいまいで最適な変換ができません。

で、

template<class T> class Class {
public:
friend void func(Class& x, Class& y) {}
};
template<class T> void func(T& x, T& y) {}

これならOK。VC7のSTLもこのパターンで実装されてる。
でも例えばfuncとClassが違う名前空間にあると
このパターンは成り立たない。色々試したがダメだった。
具体的にはstd::swapなんかを
自作のテンプレートクラスで特殊化しようとした場合なんかに
困るわけなんだな、これが。
0356デフォルトの名無しさんNGNG
なんか、テンプレートでいくらがんばっても
あんまり実りが無い感じ。
0357デフォルトの名無しさんNGNG
>>355
前半部分、13.5.1(p.404) によって後者が選ばれなきゃいけない話?
gcc 2.95ではちゃんと選ばれたよ。
0358デフォルトの名無しさんNGNG
>>357
C++の本を見る限りではそのgccの動作が正しいと思うんだけど。
VC7では選ばれる以前にコンパイルエラーになる。
多分、テンプレート関数とクラステンプレートで特殊化したテンプレート関数の
特殊化優先順位が等しいからこんなことになる。
これだったらすぐ直りそうなもんだからSPで直してほしい・・
0359デフォルトの名無しさんNGNG
メーカーの製品がこの程度の品質って、
C++のテンプレートの仕様を把握するのが一苦労って事なのかな?
0360デフォルトの名無しさんNGNG
上記の話、VC6でも確認。前からああみたいだ。

違う名前空間の関数を特殊化するなという意味だろうか。
Javaみたく階層的に名前空間分けてたら
同一プロジェクトでも同じ問題が発生するが・・
共通関数を使わずメンバ関数を使えという話になるんだろうけど
それだとSTLのうまみも半減だわな

ところでクラステンプレートをクラステンプレートで特殊化って
C++的に可能なの?VCではダメだった。
0361デフォルトの名無しさんNGNG
gccは3.0になってからその辺の構文的な要素は完全対応してるのかな?
0362デフォルトの名無しさんNGNG
>>355
Borland-C++ 5.6では正しくコンパイルできますた。
0363デフォルトの名無しさんNGNG
SDLがブレーク? フン、しねーよ。少なくともあなたには必要ないと思われ。
0364デフォルトの名無しさんNGNG
age

0365デフォルトの名無しさんNGNG
Lokiマンセー!!!
でDLしたらVC.NETじゃコンパイルできねージャン!!
氏ねMS!IDEばっか凝ってねーでコンパイラ改良しる!
0366デフォルトの名無しさんNGNG

 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄」
―――――――――――――‐┬┘
                        |
       ____.____    |
     |        |        |   |
     |        | ∧_∧ |   | C++を窓から投げ捨てろ
     |        |( ´∀`)つ ミ | 
     |        |/ ⊃  ノ |   | C++
        ̄ ̄ ̄ ̄' ̄ ̄ ̄ ̄    |    




--------------------------------------------
0367デフォルトの名無しさん NGNG
>>365
そもそもMSがcl.exeをANSIに完全対応させる気がないのだとしたら
どういう事態になるんだろう。
0368デフォルトの名無しさんNGNG
ANSIが規格をねじ曲げれば一件落着。
0369デフォルトの名無しさんNGNG
関数ポインタの配列とenumの関係で質問です。

enum {HOGE,MOGE,MONA,SAGE};
void hoge(void);
void moge(void);
void mona(void);
void sage(void);

typedef void (*FUNC)(void);
FUNC func[] = {hoge,moge,mona,sage};

こんな感じで、HOGEのときはhogeを呼ぶ、みたいに対応させてます。
このとき、enumの順番を変えたら、それに応じてfunc内の関数順番を
手動で変えるのがわずらわしいのです(enumとfuncは別ファイルです。
includeして、見えるようにはなってますけど)。
enumの順番に沿って、対応する関数がfunc内で自働的に並んでいて欲しいのです。
コンパイル時点では順番は確定しているんですから、テンプレートを
ごりごり使いこなせる人間ならできるんじゃないかと淡い期待を
持ってるんですが、どうにかして出来ませんでしょうか?
0370デフォルトの名無しさんNGNG
無理
不可能
0371デフォルトの名無しさんNGNG
>>369
なぜ順番を変えようとする?
0372デフォルトの名無しさんNGNG
数が多いなら、excelのシートに関数名とenum識別子をかいといて
VBAかなにかでボタン一個でソース吐くようにしとけば?

俺だけかもしらんが、よくやってるよ。

その場限りならセルに文字列適当に連結する式かいてコピペ、とかもやるし。
0373デフォルトの名無しさんNGNG
なぜ順番を変えるのかは突っ込まないで置こう。
見栄えが気にくわなくてあっち入れ替えたりこっち動かしたりする時期があるもんさ。
0374デフォルトの名無しさんNGNG
perlスクリプトで自動で吐くようにすればいいやん
0375デフォルトの名無しさんNGNG
ちょっと面倒だけど、こんなん駄目?

#include "stdafx.h"

template< int > struct Function{};
#define DEF_FUNC( index, func ) template<> struct Function<index>{ \
static void call(void){ func(); } }

enum {HOGE,HAGE,};
void hoge(){puts("hoge");}
void hage(){puts("hage");}

DEF_FUNC( HOGE, hoge );
DEF_FUNC( HAGE, hage );

int main(int argc, char* argv[])
{
Function<HOGE>::call();
Function<HAGE>::call();
return 0;
}
0376375NGNG
ガーン!
今頃気づいたけど、呼び出し時のインデックスはコンパイル時には確定してないのか・・・じゃ駄目だ。
0377375NGNG
上のを修正。
ちょっとオーバーヘッドがあるけど、
(テンプレートクラス内のcallをfuncへのポインタに出来ればいいんだろうけど、俺はやり方知らない。)

void (*funcs[])(void) = {
Function<HOGE>::call,
Function<HAGE>::call
};

int main(int argc, char* argv[])
{
for( int index = HOGE; index<=HAGE; ++index )
{
funcs[index]();
}
return 0;
}
0378デフォルトの名無しさんNGNG
> void (*funcs[])(void) = {
> Function<HOGE>::call,
> Function<HAGE>::call
> };

それだと結局、enumを
 enum {HAGE,HOGE,};
に変えられたときにマズーではないか?
0379375NGNG
ぐわぁ!
やっちまった(藁
0380デフォルトの名無しさんNGNG
>>375-377
ちょっとなぁ、という気がする。
自分が書くにはいいが、人には見せられない。

そもそも、見栄えを気にする(順番を入れ替える)んだから、
その書き方はいいとは思えない
0381375NGNG
>>380
つーか普通はこんなことしねぇって。
0382375NGNG
こら待て、今気づいたんだが、375でいいじゃねぇかよ。
enum値と対応させるってことは配列のインデックスは手打ちでenumの値を書くってことだろ?
インデックスが実行時に決まるならenumに対応させる意味もないし。
0383デフォルトの名無しさんNGNG
enum {
 HAGE,
 HOGE,
};

template<int i>
void f();

template<>
void f<HAGE>()
{
 return;
}

void f<HOGE>()
{
 return;
}

void (*func[])() = {
 f<HAGE>,
 f<HOGE>,
};

0384デフォルトの名無しさんNGNG
あ、ダメやん・・・(鬱
0385369NGNG
Modern C++ のInt2Typeとかをみてると、なーんかできそうな気がしてくるんですよねー。
どうやればいいのかはさっぱり分かりませんけど。

>>382
いや、呼び出すときは (*func[n])() ですが…。
対応させる意味がない…? えーと。考えます。
0386デフォルトの名無しさんNGNG
おいおい、じつはCOMだから関数の順序が....とかなんとか理由つけてくれよ
0387デフォルトの名無しさんNGNG
>>385
テーブルを動的に作るのはだめなん?
0388デフォルトの名無しさんNGNG
>>387
俺もそう思う。
0389369NGNG
えーとですね。ふたつの実行ファイルが、enum値に依存してるわけなんです。
エンコーダとデコーダを作ってまして。
エンコーダは、テキストの文字列 "hoge" "hage"を読み込んで、
バイナリでenum値「HOGE,HAGE」を吐きます。んで、
デコーダは、バイナリでHOGE,HAGEをみて、関数hoge(),hage()を呼ぶ、と。
そういう状況です。

>>テーブルを動的に
いや、いいんですけど。でも、静的に解決できることじゃないですか。
出来たらかっこいいじゃないですか。そういうスレじゃないですか、ここは。
0390デフォルトの名無しさんNGNG
>>389
もし出来たとしても決してかっこよくはならないと思うぞ。
0391デフォルトの名無しさんNGNG
#include <iostream>
using std::cout;
using std::endl;

enum {SAGE,MONA,MOGE,HOGE, END}; // ←ここ順番変えてよし!
typedef void (*FUNC)();
void hoge() { cout<<"hoge"<<endl; }
void moge() { cout<<"moge"<<endl; }
void mona() { cout<<"mona"<<endl; }
void sage() { cout<<"sage"<<endl; }

template<int> inline void f() {}
#define ASSOC_FUNC(E,F) template<> inline void f<E>() { F(); }
ASSOC_FUNC(HOGE,hoge)
ASSOC_FUNC(MOGE,moge)
ASSOC_FUNC(MONA,mona)
ASSOC_FUNC(SAGE,sage)
FUNC func[] = { f<0>, f<1>, f<2>, f<3> };

int main()
{
for( int i=0; i<END; ++i )
func[i]();
return 0;
}

…と思ったんだけど、関数ポインタ経由だからinline展開されないよなぁ、これ…。
0392デフォルトの名無しさんNGNG
文字列からenum値に変換するのか?
それだったら、
std::map<std::string, void(*)()> m;
m["hoge"] = hoge;
これでいいじゃん。
0393デフォルトの名無しさんNGNG
文字列->定数で解決したいんだろう

試みとしてはおもしろいかな。
でも、おれの知識じゃまだ無理だなあ。
Modern もっとよむか
0394デフォルトの名無しさんNGNG
なんかみんな無理してるよね(w
それがもの凄く伝わってくるスレ
0395デフォルトの名無しさんNGNG
>>391
改造してみた、本末転倒?

#include <iostream>
using std::cout;
using std::endl;

enum {SAGE,MONA,MOGE,HOGE, END}; // ←ここ順番変えてよし!
#define sage f<SAGE>
#define mona f<MONA>
#define moge f<MOGE>
#define hoge f<HOGE>

typedef void (*FUNC)();
template<int> void f() {}
template<> void sage(){cout<<"sage"<<endl;}
template<> void mona(){cout<<"mona"<<endl;}
template<> void moge(){cout<<"moge"<<endl;}
template<> void hoge(){cout<<"hoge"<<endl;}

FUNC func[] = { f<0>, f<1>, f<2>, f<3> };

int main()
{
for( int i=0; i<END; ++i )
func[i]();
return 0;
}
0396デフォルトの名無しさんNGNG
>>395
全然かっこよくないぞ
0397デフォルトの名無しさんNGNG
もはやかっこよさなんてどうでもいい罠
0398369NGNG
かっこよさ以前に、ちゃんと動作してくれないんですが…。VCのせい?
0399デフォルトの名無しさんNGNG
>>396
Modern(の前半)読んでかっこいいと思ったか?
俺は、すげぇとは思ったがかっこいいとは思わなかったよ(むしろ汚い)。
このスレで今やってることも同じようなもんさ。
おとなしく動的作成にしない389が悪い。
0400デフォルトの名無しさんNGNG
>>398
#include "stdafx.h"
をソースファイルの先頭に入れ忘れてるとか。
0401デフォルトの名無しさんNGNG
関数テンプレートのテンプレートパラメータに定数を使うのは、
VCだとバグのせいでうまくいかなかったはず。
たしか、すべて同一の実体を指すようになってたような。
0402デフォルトの名無しさんNGNG
そういえばそうだったな。
他のに乗り換えれ。
0403デフォルトの名無しさんNGNG
#include <iostream>

template <int i> void func()
{
 std::cout << i << std::endl;
}

int main()
{
 func<0>();
 func<1>();
 return 0;
}

これをコンパイルしてみればわかる
0404デフォルトの名無しさんNGNG
結局、VC(6以下)使ってる限りは無理って結論でよろしいか?
0405369NGNG
両方とも 1 が出力されました…。 (T_T)
0406デフォルトの名無しさんNGNG
関数テンプレートにせずに、クラステンプレートにすればいいやん。

template<int i> class func {
public:
 func() {
  std::cout << i << std::endl;
 }
};
0407デフォルトの名無しさんNGNG
すげー見にくくなってきたな・・・
0408369NGNG
たしかにクラステンプレートならVCでもいける…。
で、あとは391と組み合わせれば…?
0409369NGNG
コンパイルが通らない…。(T_T)
どうすれば…。
0410デフォルトの名無しさんNGNG
>>409
ヒント

enum {
 HAGE,
 HOGE,
};

class FuncBase {
public:
 virtual void operator()() { }
};

template<int i> class FuncObj;

template<>
class FuncObj<HAGE> : public FuncBase {
public: void operator()() {
   std::cout << "hage" << std::endl;
  }
} hage;

template<>
class FuncObj<HOGE> : public FuncBase {
public: void operator()() {
   std::cout << "hoge" << std::endl;
  }
} hoge;

FuncBase* func[] = {
 &hage,
 &hoge,
};

int main()
{
 (*func[HOGE])();
 (*func[HAGE])();
 return 0;
}

テーブルに登録するところをいじってくれ
0411デフォルトの名無しさんNGNG
正直、>>410みたいにしてまでコンパイル時に決定したいとは思わないが。
0412デフォルトの名無しさんNGNG
とりあえずなんでもかんでも関数オブジェクトにしちまうか....
最悪だな
0413デフォルトの名無しさんNGNG
はっきりいって、ここまでしてやることじゃないと思う
0414デフォルトの名無しさんNGNG
やっぱり、動的にテーブルを作るのが一番って事で、

********************** 終了 ************************
0415369NGNG
出来ました!
>>395にはかないませんけど、>>391より効率よく、なおかつVC6でも動きます。

#include <iostream>
using namespace std;

enum{HOGE,MOGE,HAGE,SAGE};// ←順番は任意に入れ替え可能
void hoge(void){cout<<"hoge"<<endl;}
void sage(void){cout<<"sage"<<endl;}
void moge(void){cout<<"moge"<<endl;}
void hage(void){cout<<"hage"<<endl;}

typedef void (*FUNC)(void);

template<int v>
struct f{
static FUNC f_;
};
#define ASSOC_FUNC(A,B) template<> FUNC f<A>::f_ = B;
ASSOC_FUNC(HOGE,hoge)
ASSOC_FUNC(HAGE,hage)
ASSOC_FUNC(SAGE,sage)
ASSOC_FUNC(MOGE,moge)
#undef ASSOC_FUNC

FUNC funcTable[4] = {f<0>::f_ ,f<1>::f_ ,f<2>::f_ ,f<3>::f_ };

int main(int argc, char* argv[])
{
for (int i=0;i<4;++i)
(funcTable[i])();
return 0;
}
0416デフォルトの名無しさんNGNG
初期状態よりも何倍も汚くなっている罠
0417デフォルトの名無しさんNGNG
まさに自己満足以外の何者でもない
0418デフォルトの名無しさんNGNG
プログラムの半分は自己満足で出来ています。
0419デフォルトの名無しさんNGNG
自己満足っつーか、ひとりよがり、って感じ。
0420369NGNG
うえーん、一生懸命考えたのに、ボロクソ言われてるよー
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
            ∧_∧
          ( ´Д⊂ヽ
          ⊂    ノ
           人  Y
          し (_)


(´-`).。oO(っていうか、考えついたのが満足であって、>>415を使ったりはしないけどね…)
(´-`).。oO(.NETなら>>395を使えるのかしら?)
0421デフォルトの名無しさんNGNG
とりあえず、よくやった。
でも誰も使うことはないだろう。
0422デフォルトの名無しさんNGNG
筋トレと同じ。
これが実戦と同じだと勘違いしたら問題だが、
こういう鍛え方でしか鍛えられないことはある。
どんどんやるべきだと思うよ。
0423デフォルトの名無しさんNGNG
見せるため、自己満足のための筋トレと
運動するための筋トレはまったく別物。

鍛え方を間違っちゃいかん。
0424デフォルトの名無しさんNGNG
八頭身の予感 age

0425369NGNG
ポリシーやらファンクタやらを勉強ししてて、ふとこんな構文が
通ることに気付いてしまいました。

#include <iostream>
using namespace std;

class Hoge
{
public:
void operator()(void){cout<<"hoge"<<endl;}
};

int main(){
Hoge()();// ←なんと奇怪な構文!
return 0;
}

…うわー。これ、ホントに通っていいんですか? まあ、理屈には合ってますけど…。
(最初のカッコでHogeのデフォルトコンストラクタでテンポラリインスタンスを生成。
次のカッコでHogeのoperator()を呼び出す)

VCだけじゃないことを祈りまふ…。

ちとスレ違いかな。sage.
0426デフォルトの名無しさんNGNG
>>425
それ、普通だが?
文が完了するまで一時オブジェクトの寿命が続くはず。
Hoge(), foo(), bar();
こうすると、bar()の後にHogeのデストラクタが呼ばれる
0427369NGNG
いや、奇怪だっつーてるのは、カッコが連続してることです。
コンストラクタやoperator()の引数次第で、関数宣言だとか
関数ポインタだとか、そのあたりと間違えてしまいそうな構文だなーと。
0428デフォルトの名無しさんNGNG
関数オブジェクトを作り始めれば、別に不思議に思わなくなるよ。
0429デフォルトの名無しさんNGNG
>>425
struct Hoge { Hoge& operator()(void){return *this;} };
int main() {
  Hoge()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()();
}
…はともかくとして、何の変哲もないふつうの構文だと思うよ。

> 関数宣言だとか関数ポインタだとか、そのあたりと間違えてしまいそうな構文
引数付きのコンストラクタを呼び出したりする時に、
下手すると関数宣言扱いになっちまうことはあり。
Effective STLとか参照。
0430デフォルトの名無しさんNGNG
>>425
それ、Cでも通らん?

#include<stdio.h>

typedef void (*fp)(void);
typedef fp (*fpp)(void);

void hogegege(void)
{
printf("\nhogegege\n");
return;
}

fp hogege(void)
{
printf("\nhogege\n");
return(hogegege);
}

fpp hoge(void)
{
printf("\nhoge\n");
return(hogege);
}

int main (int argc, char argv[])
{
hoge()()();
return(0);
}

----
/tmp>gcc hoge.c
/tmp>./a.out

hoge

hogege

hogegege
/tmp>
0431デフォルトの名無しさんNGNG
>>430の登場によって、>>425のささやかな期待は、崩れ去ろうとしている。
しかしそれはC++信望崩壊への、ほんの序曲でしかなかった──────。

425「げ、良く考えたらどれもこれも、Cで作れるじゃん!」
430「それ、Cでも通らん?」
413「はっきりいって、ここまでしてやることじゃないと思う」
426「それ、普通だが?」
425「し、Cマンセー!C++なんてクソ。これ定説!」

だれかprojクトX風に仕立ててくれ。
0432デフォルトの名無しさんNGNG
                 ( ̄ ̄<     / ̄>
                  \  ヽ   / /ソ
        プ ロ ジ ェ ク ト\  ヽ P r o j e c t X
   ─────────────────────
         Generatorたち /|_/ /\Generators
                 |   /   \   丶
                 \/       \__ノ
Genericスレッド。
このスレで425は一人で悩んでいた。なぜこんな構文が許されるのかと。
「いや、関数オブジェクトでは当たり前だ。」
「こんな物は普通だ。」
次々とヤジが飛ぶ。へこんだ。
万策尽き果てたとき、ふと430が現れる。
「Cでも出来るんじゃないか?」
これは、C++に翻弄された男たちの物語である。

風の中のスバル〜♪
0433デフォルトの名無しさんNGNG
まぁ変な書き方とかは狙えばいくらでもできるからね

1+-+-+-+-+-+-+-+1 とか
■ このスレッドは過去ログ倉庫に格納されています