【C++】template 統合スレ -- Part3

このエントリーをはてなブックマークに追加
C++ のジェネリックプログラミングの話をしましょう。
以下のスレッドを統合するスレです。

STLスレッド
Part1 http://pc.2ch.net/tech/kako/1004/10042/1004287394.html
Part2 http://pc3.2ch.net/tech/kako/1026/10267/1026793823.html

【C++】Boost使い集まれ!
http://pc3.2ch.net/test/read.cgi/tech/1033830935/ (html化待ち?)

Generic Programming with C++ Template
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html
【C++】template 統合スレ -- STL/Boost/Loki, etc.
http://pc2.2ch.net/test/read.cgi/tech/1037795348/
【C++】template 統合スレ -- Part2
http://pc2.2ch.net/test/read.cgi/tech/1047978546/ (html化待ち)

関連スレ、その他リンクは >>2-5 あたりに。
リンク修正(Part2と同じ事やってる(^_^;)
【C++】Boost使い集まれ!
http://pc2.2ch.net/test/read.cgi/tech/1033830935/
>>1
激しく乙
あと、腐ったstd::valarrayの後釜として次期標準化の呼び声が高いBlitz++
http://www.oonumerics.org/blitz/
宣伝ご苦労
8デフォルトの名無しさん:03/10/19 06:51
Part4まだかな〜
9デフォルトの名無しさん:03/10/19 10:59
Zカレー
>>11
次ぎスレはいらないって・・・・ぷっぷぷぷ
次スレを「つぎすれ」と読むのは小学生に違いない。
小学生もテンプレートメタプログラミングをする時代になったのか。
閑古鳥が鳴いています。
日本シリーズ見るから静かにしてください
std::valarrayって、具体的にどう腐ってるんだろう
>>16
1.サブセットを取り出す場合明示的なキャストが常に必要となる。
2.slice同士の演算も明示的なキャストが必要であり面倒。
3.sliceをvalarrayに変換する際に巨大な一時的なオブジェクトが
  作られ、パフォーマンスが悪い。

結果としてFORTRANの代替用として使うにはあまりにも効率が悪すぎ、
書式も複雑になりすぎる嫌いがある。

本当はこの当たりをもっと煮詰めてから標準化する予定だったらしいが、
std::valarrayの開発者が途中で標準化委員会を抜けてしまったため、ほ
とんどそのまま放置され、未完成のまま世に出てきたと言われている。
おそらく標準委員会の方達に嫌気がさしたのでしょう
その名は、Kent "Frankenstein" Budge。
つかなんでvector<bool>は特殊化したのよ。
そんなビット単位でぎちぎちに詰めたいやつはそもそもvectorなんか使わんでしょうに。
悪い特殊化の見本に。
その調子で組込型のvector全部特殊化して欲しかったな。
>>22
全部って何を?
俺はvoid*の特殊化がほしいけど
24デフォルトの名無しさん:03/10/22 18:57
マスタをlistにつんで検索とかやってますが、マスタの件数が多くなるとさすがに遅い。
listじゃなくvectorにして二分木検索とかにしたら早いかなと思ってますが、そんなサンプルなんてどこかに落ちてないですか?

自分でしこしこ作らないと駄目かなぁ?
>>24
二分木探索なら STL の <algorihm> で提供されてるぞ。lower_bound, upper_bound
std::mapの代わりに整列済みstd::vectorを使うってのならLokiにあるが。
27デフォルトの名無しさん:03/10/24 20:20
>>26
AssocVector ?
28デフォルトの名無しさん:03/10/25 12:02
VS.NET 2003 のC++コンパイラのバージョンってどれなんでしょうか?
バージョン情報をみても Microsoft Visual C++ .NET ******-***-********-***** としか書いて無いんです。
というのは
http://boost.sourceforge.net/regression-logs/
を見ていて、このコンパイラはどれに当たるのだろうかと?
>>28
VC++ 7.1

ちなみに素の VS.NET が VC++ 7.0
>>29
あっ、どうもです
31デフォルトの名無しさん:03/10/26 14:16
boost::lambda::bind<int>(
とやるとVC7.1が固まってしまう...
再インスコしたら直ります?
してみろよ。
>>31
コンパイル時でなくて、コード入力時(インテリセンスの問題)だよな?
だったら、たぶん直らない。
自分の環境でも、100%固まる特定の記述が何回かあった。
いつも、そこだけ他のテキストエディタで書いて誤魔化している。
3431:03/10/26 18:11
>>33
やはりそうでしたか。
とりあえず、
テキストエディタの設定で
パラメータヒントをOFFにしてみたら
固まる症状はでなくなりました。
ありがとうございました

35デフォルトの名無しさん:03/10/27 22:46
すいません、人様に教えて頂いたコードが2,3日かけてもまるでわかりません。
std::mapが入ってくるんで一応こっちで聞かせてください!
やりたいことは、拡張子に対応するアイコンのインデックス値を
システムイメージリストから調べて拡張子をそのまま変数に、対応するインデクス値を「値」に、
AnsiString jpg=3;
AnsiString html=6;
(みたいにして構造体に突っ込んでいく)というものなのですが、
教えて頂いたのが以下のコードです。

class IndexMap {
 std::map<AnsiString, int> index_map;
public:
 int operator()( const AnsiString& ext ) {
 if ( index_map.find(ext) == index_map.end() ) {
  //indexの取得
  index_map[ext] = index;
 }
 return index_map[ext];
};

んで毎回拡張子を判定してアイコンをリストビューに表示させてた以前のコードがこれ

void __fastcall TForm1::AddListView( const AnsiString DirName , TListItem *Items )
{
AnsiString Ext =ExtractFileExt( DirName );
SHFILEINFO fileinfo;
::SHGetFileInfo( Ext.c_str(), NULL, &fileinfo,
sizeof(fileinfo),SHGFI_USEFILEATTRIBUTES | SHGFI_ICON | SHGFI_SMALLICON );
 Items->ImageIndex = fileinfo.iIcon;
}
教えて頂いたコードのoperator()()(オブジェクト関数、らしい…)とか検索しても
上手く使い方が見つからないし、どうやって使ったらいいかお手上げ状態で、
我流にやってもエラーばっかり出ます。
[C++ エラー] hoge.cpp(50): E2015 '_fastcall System::operator +(int,const System::Currency &)' と '_fastcall System::operator +(int,const System::Variant &)' の区別が曖昧
おまけにこちらも初めて見るstd::mapがどう動いているのかもわからないし…。
お願いします、この場合、以前のコードをどう組み込んで、
どういうオブジェクト関数の呼び方をするのが正解なんでしょうか。
よければ正解のコードを教えて頂ければ自分であれこれ試して勉強させて頂きます。
あ、すいません、カッコがちゃんと閉じてなかったですね

class IndexMap {
 std::map<AnsiString, int> index_map;
public:
 int operator()( const AnsiString& ext ) {
  if ( index_map.find(ext) == index_map.end() ) {
   //indexの取得
   index_map[ext] = index;
  }
 return index_map[ext];
 }
};
IndexMap map;
int index = map( ".jpg" );
オブジェクト関数か・・・関数オブジェクトの間違いだと想像しておく。

エラーメッセージの詳細は最低限ソース晒してコンパイラスレ池。
どうせintと変なオブジェクトの加算をしてるが、その変なオブジェクトからVariant、Currencyへの変換が定義されててどっち使えばいいかわから無いってことじゃねぇの?

map はソースか本読め。
>>37
これでいいでそ。スタティックメンバ変数は、どっかに
std::map<AnsiString, int> IndexMap::index_map;
って実体書いといてね。

class IndexMap {
 static std::map<AnsiString, int> index_map;
public:
 static int Ext2Index(const AnsiString& ext) { ... };
};

void __fastcall TForm1::AddListView( const AnsiString DirName , TListItem *Items )
{
 AnsiString Ext =ExtractFileExt( DirName );
 Items->ImageIndex = IndexMap::Ext2Index(Ext);
}
>>38
アドバイスどうもありがとうございます!
>>39
ああ、ありがとうございます!でも駄目です!
コンパイルエラーは出なくなったんですが、
アプリケーションのくだんの関数実行中にエラーが出てきます。むう。
「モジュール'vcl60.bpl'のアドレス 4013D550でアドレス6F726404に対する読み込み違反がおきました。」

とりあえず.cppの#includeの下に以下を書いたんですが…
自分で書いた怪しいところはコメントアウトしてから実行しました。

class IndexMap {
static std::map<AnsiString, int> index_map;
public:
static int Ext2Index(const AnsiString& ext) {
//SHFILEINFO fileinfo;
//::SHGetFileInfo( ext.c_str(), NULL, &fileinfo,
//sizeof(fileinfo),SHGFI_USEFILEATTRIBUTES | SHGFI_ICON | SHGFI_SMALLICON );
//return fileinfo.iIcon;
};
};
std::map<AnsiString, int> IndexMap::index_map;

あと、基本的にアイコン付きのリストビュー表示を可能な限り早く行うための関数なので、
可能な限りSHGetFileInfo()をの数を減らす、つまり、既出の拡張子は即座にアイコンindex値を
返すのが目的なんです。
なのですでに登録されてる拡張子はすっ飛ばしてindex値を返す処理が必要だと思うんですが、
これってもしかして別関数でファイルを検索してこのIndexMapが呼ばれるたびにSHGetFileInfo()
が実行されちゃうんでしょうか…。

しかし、こういう呼び方するんですね、勉強になりました…。
IndexMap::Ext2Index(Ext);
なんでstatic?

class IndexMap
{
 typedef std::map<AnsiString, int> map_type;
 map_type m_map;
public:
 int operator()( const AnsiString& ext ) {
  map_type::iterator const bound = m_map.lower_bound( ext );
  if ( bound != m_map.end() && !m_map.key_comp()( ext , bound->first ) ) {
   return bound->second; // すでに登録されている
  }
  // 新しく登録
  int const index = m_map.size();
  m_map.insert( bound , map_type::value_type( ext , index ) );
  return index;
 }
};

で、インデックスは連番でいいのかな?
なんでスタティックかというと、拡張子 -> システムアイコンリストのインデックスなんて
いう map はシステムで1個あればよいものだから。シングルトンにするほどのものでも
ないし。

インデックスは連番じゃなくて、
SHFILEINFO fileinfo;
::SHGetFileInfo( ext.c_str(), NULL, &fileinfo,
 sizeof(fileinfo),SHGFI_USEFILEATTRIBUTES | SHGFI_ICON | SHGFI_SMALLICON );
return fileinfo.iIcon;
こんな感じで得られる。

ところで、40 はこんなことろでグダグダ質問してないで、C++ とか C を勉強したほうがいいよ。
こうやって人に聞くことには何の意味もないよ。
つか、>>40氏よ。初心者スレ立ってるよ。
>>41
あぁ、ありがとうございます!なにやら光が見えてきましたぁ!ような気がします_| ̄|○
難しいですねー。ありがとうございます。

>>42
先ほど答えて頂いた方ですね。その節はどうもありがとうございます。
参考書も何もなしで、webに転がってる解説だけで来たんですがそろそろ限界です(;´Д`)
プログラムと言えばちょっとperlのcgi改造するくらいとFlashのアクションスク(ry

>>43
あぁ、ご親切どうも。実はあっちで以前に聞いて教えて頂いたコードが難しくて、
延々と検索してもいまいちわからなかったので
関係ありそうなこちらで聞かせて頂いたんです。
>>42
システムで唯一でなければならないならともかくその程度ならstatic使うほうが
後々問題になる確率が高そうだが。
>>45
システムで唯一でなければならないんですよ。
次のBoostは来月か・・・
>>46
だったら IndexMap のインスタンスを static にすればいい。
「拡張子 -> システムアイコンリストのインデックス」が「システムで唯一でなければならない」としても、
class IndexMap のメンバを static にする必要は無い。
>>48
どんなクラスの static 変数にするのが妥当だと思います?
典型的なシングルトンパターンで、かつ初期化に関する問題の無いもの
だから、このクラス単体で(何かを) static にしとくのが良いと思うんだけど。。

煽りじゃなくて、単純にどういう方法論から出てくる意見なのか知りたくて
質問しますた。
>>49
多分俺ならIndexMapをクラスにせず
class FileSystem
{
 static std::map<AnsiString, int> ExtensionToIconIndex;
};
にすると思う。
拡張子とかイメージリストのインデックス、という情報はデータの構造ではなく意味だから。

マップに入れるデータの意味ごとにいちいちクラスを作っていたら爆発するよ。
51デフォルトの名無しさん:03/11/01 18:00
auto_arrayみたいなものが欲しい時はLoki入れるか自作しないとだめ?
boostにあるよ
>>52
thx!
でもsandboxか・・・
コピペして使ってみるよ。
>>51
std::vector
boost::scoped_array
55デフォルトの名無しさん:03/11/01 19:05
STLport-4.6 age
using namespace std;
vector<pair<int, int> > pairs;
pairs.push_back(pair<int, int>(1,5));
pairs.push_back(pair<int, int>(2,10));
pairs.push_back(pair<int, int>(3,3));
pairs.push_back(pair<int, int>(4,8));
//second()の小さい順にソート
sort(pairs.begin(), pairs.end(), boost::bind<
less<int, int>(),
boost::bind<pair<int, int>::second, _1>,
boost::bind<pair<int, int>::second, _2> >);

こんなことやってる人居ますか?
コンパイルとおらないね。
それコンパイルとおる?
5958:03/11/03 09:18
かぶった。俺だったらこうする。

struct cmp{
bool operator ()(const pair<int, int> &a,const pair<int, int> &b){
return a.second<b.second;
}
};
sort(pairs.begin(), pairs.end(),cmp());
>>59
ファンクタにコンストラクタつけて、lessとgreaterの両方を比較する
オプション付けるとか。
>>60
意味わかんない。
>>61
std::sortの第3パラメータにstd::lessとかstd::greaterとかの事前定義の
BinaryPredicateを与えると便利という意味。

std::sort(paris.begin(), pairs.end(), cmp(std::greater<int>())); とかね。
ちくしょう。cmpのコンストラクタに引数をstd::binary_predicate<const Pairs&, const Pairs&,
bool> で受けたけどうまくいかない。仕方ないからenumで受けた。
関数オブジェクトって初期化時にパラメタとして渡せないんだっけ?

typedef std::pair<int, int> Pairs;
enum Mode {less, greater};

struct cmp {
cmp(const Mode& p) {
if (p == greater) m = greater;
else m = less;
}
bool operator()(const Pairs& a, const Pairs& b) const {
return a.second < b.second;
}
private:
Mode m;
};
続き

std::ostream& operator<<(std::ostream& os, const Pairs& p)
{
os << p.first << ' ' << p.second;
return os;
}

int main()
{
std::vector<Pairs> pairs;
pairs.push_back(Pairs(1,5));
pairs.push_back(Pairs(2,10));
pairs.push_back(Pairs(3,3));
pairs.push_back(Pairs(4,8));

//second()の小さい順にソート
std::sort(pairs.begin(), pairs.end(), cmp(greater));

std::copy(pairs.begin(), pairs.end(), std::ostream_iterator<Pairs>(std::cout, "\n"));
}
ちいとcmpを修正。

struct cmp {
cmp(const Mode& p) {
if (p == greater) m = greater;
else m = less;
}
bool operator()(const Pairs& a, const Pairs& b) const {
return (m == less) ? a.second < b.second : a.second > b.second;
}
private:
Mode m;
};
6658:03/11/03 15:10
毎回余分な比較が入るぞ、それ。見本として作るならこうかな。

template <class Fun>
struct cmp2nd_t {
cmp2nd_t(Fun f):fun(f){}
template <class T,class U>
bool operator()(const T& a, const U& b) const {
return fun(a.second,b.second);
}
private:
Func fun;
};

template <class Fun>
inline cmp2nd_t cmp2nd(Fun fun){
return cmp2nd_t(fun);
}


sort(p.begin(),p.end(),cmp2nd(std::greater<int>()));


試してないからコンパイル出来ないかも
6758:03/11/03 15:11
template <class Fun>
inline cmp2nd_t<Fun> cmp2nd(Fun fun){
return cmp2nd_t<Fun>(fun);
}
>>66>>67
すげぇ、通りました。ありがとうございます!
関数オブジェクトを関数ポインタとして持ってしまうのかな?
std::greaterとstd::lessの二種類でソートしてみると、
デバッグで追いかけるとそれぞれの2項関数オブジェクトの
cmp2nd_tの実体が作られ、それぞれを別個にCALLしていま
した。最適化によってstructの中身が分解されたみたいです。
(Borland-C++ 5.6.4)

それにしても標準の二項述語をいきなりtemplateで受けるとは
恐れ入りました。もっと精進します。
6956:03/11/03 17:29
すみません、ちょっと間違えていました。

//secondの小さい順にソート
sort(pairs.begin(), pairs.end(), boost::bind(
less<int, int>(),
boost::bind(&pair<int, int>::second, _1),
boost::bind(&pair<int, int>::second, _2)));

vc7.1で通りました。
しかし、ちょっと話題はずれるけど、

std::ostream& operator<<(std::ostream& os, const Pairs& p)
{
os << p.first << ' ' << p.second;
return os;
}

std::copy(pairs.begin(), pairs.end(), std::ostream_iterator<Pairs>(std::cout, "\n"));

このコードBCCでは通るけど、VC7.1、gcc3.1.1(MinGW)では通らねーな。
std::coutなどに<<を食わせるのと、std::ostream_iteratorに食わせるのでは
何が違うのかな。
だめ、降参俺にはその問題解けないわ。
vc7.1の場合、内部的には
basic_ostream<char,char_traits<char> >* myos = &cout;
*myos << pairs[?];
こんな事やっているだけなのになんでだろう
コンパイル順序が関係してるとしか思えなのだがわからない。
>>71
不思議だよねえ。でも多分標準準拠度は
VC7.1>gcc3.3.1>BCCだから、BCCが甘いだけなのか、
BCCはSTLPortを標準搭載だからVC7.1やgccにSTLPortを
入れたら通るのか、これは実験の余地がある。
丁度STLPort4.6が出た所だし試してみるか。
>>72
よろしくお願いします。・・・・。
\(*⌒0⌒)bがんばって♪
>>73
でもさ、STLPortのビルドって難しいので有名なんだよね。
いまちょっとMinGWでやってみたら「コマンドラインが違います」とか
4連発で出てきやがった。cppllで聞いてみるか。バカにされるか
相手にされないかのどちらかだろうな。
boostのthread使いたいんだけど
VC7.1+STLportのiostreamでどうやってビルドすればいいんだろ?
オプションとしてmsvc-stlportとvc7.1ってのがあるんだけど
どちら選べばうまくいくんだろ
>>70
namespace が鍵のようだ。
>>76
namespace std
{
  std::ostream& operator << (std::ostream& out, const std::pair<int,int>& p)
  {
    out<<p.first<<' '<<p.second;
    return out;
  }

}
ほんとだべ。
♪ルンルン♪o(^0^o)♪~(o^0^)o ~♪♪~o(^0^o)~♪(o^0^)o~♪ランラン♪
でも一回目試したときはうまくいかなかったよう気がしたんだけどな。
やり方がわるかったのか。
>>72にも早く教えてやらねばー
やっぱり、まだvc7.1の最強伝説は崩れなくてよかった。www
> やっぱり、まだvc7.1の最強伝説は崩れなくてよかった。www
vc7.1持ってないんだけどさ、
・非const参照に一時オブジェクトがバインドされる
・メンバ関数へのポインタが & 無しで取れる
とか、「コンパイルが通ってしまう」系のバグも直ってるの?
>>78
直ってない。
>・非const参照に一時オブジェクトがバインドされる
warningにはなる。
>・メンバ関数へのポインタが & 無しで取れる
単純なメンバ関数ポインタなら何も言わずに通るが、特定の状況では&付きの記述が必要。
(ただ、これはこれで便利なんだよな。)
>>77
それじゃ解決して無いだろ。
>>77
名前のルックアップが出来ないためだと思われる。
もし二個目の引数がstd::pairじゃなく独自のものだったらちゃんとなると思う。


名前のルックアップ(Keonig ルックアップとも呼ばれる)とは、
パラメータクラスに関係のある非メンバ関数を
public インタフェースのものと拡大解釈することにより、名前の修飾の省くことをいう。
>>81
  std::cout << pairs[0] << "\n";
// std::copy(pairs.begin(), pairs.end(), std::ostream_iterator<Pairs>(std::cout, "\n"));

上がオーバーロード有効で下がオーバーロード無効なのが問題なので、
「名前のルックアップが出来ない」わけじゃないと思う。
>>77
72です。
おわっ、本当だ。通る。
operator<<にstd::pairを渡すとこういう罠があったとは・・・・・

>>82
そうなんですよ。俺も同じ事をやってみたら上はちゃんと
通るので、??と頭をかしげていました。std::ostreamクラス
のfriendとして<<を定義できれば問題もなくなるかも・・・って
そういう問題じゃないな。

Effective STLのP176で、boost::shared_ptrのlessをstdの中
に入れている例があるが、今回もこれと同じようなケースかいな。
> Effective STLのP176で、boost::shared_ptrのlessをstdの中

それは特殊化を同じ名前空間で行う必要があるからで、今回の件とは別だと思います。
8578:03/11/04 10:25
>>79
情報ありがとう。
バグだってのはわかってるはずなのに変わってないって事は、
MSの都合なんだろうな。
8678:03/11/04 10:41
s/変わってない/直ってない/
>>86
いや、バグじゃないような気がします。
なんか、プログラミング言語C++第3版の名前空間の名前の照合というところで(p.224)
関数は呼び出しのスコープ(いつものとおり)とすべての引数の名前空間(各引数のクラス、基底クラスを含む)から
探索され、見付かったすべての関数の中で通常の多重定義解決が行われる。

ゆえに、名前空間内のクラスからは宣言でもしない限りグローバルなスコープが存在しないのが
正しい解釈なのではないのでしょうか違いますかね?

英語よめんからこんな解釈しか出来なくすみません
「あ゛」ちがったごめんなかった事にしてください
で、誰かSTLPort4.6のMinGWでのビルドに成功した人いる?
ようやくみつけたような気がする。

14.6.4 -1-
"In resolving dependent names, names from the following sources are considered:
 ・Declarations that are visible at the point of definition of the template.
 ・Declarations from namespaces associated with the types of the function arguments
  both from the instantiation context and from the definition context."

ということで、
"Dependent name"(テンプレート引数に依存した識別子およびoperator)の解決には以下のものが考慮される。
・テンプレート定義の時点で可視となる宣言
・関数引数の型に関連するnamespace中で定義時および実体化時両方のコンテキストの宣言

>>70の例では、 operator<< の解決に
・ostream_iterator::operator= の定義時で可視な operator<<
・namespace std の中の operator<<
が使われることになり、 ::operator<< は見つからない。

つまり、typedefの属するnamespaceは引数に関連しているとはみなされず、
引数に依存した参照が、見た目から期待される範囲と異なることがあるので注意が必要ってわけですよ。
>>90
70です。わざわざ探して下さってありがとうございました。
namespace stdの中に入れる小技も教えて頂きました。

さらなるSTLの使用拡大に向けて社内でも勉強会などで
どしどし洗脳していきます。車輪の再発明は避けたいし。
9287:03/11/05 13:01
でも、こんな落とし穴があったとは今まで誰も疑問に思わなかったのだろうか。
これからはSTLでグローバルなオーバーロード関数を使いたいときははstd空間でぐぐらなきゃ。
>>92
落とし穴っつーか・・・常識だが?
9487:03/11/05 15:59
>>93
そうだったのか。
。・°°・_〆(・o・ ;)・°°・。メモメモメモメモ・・・
>std::ostream &operator<<(std::ostream &, const std::pair<int, int> &)
こんな多重定義をしてはならんと思うのは漏れだけ?
>>95
ではどうすればいいと?
>>96
少なくともひとつの、「自分で定義した」型に依存させる
例えば、
class My_pair : private std::pair<int, int>{/* ... */};
std::ostream &operator<<(std::ostream &, const My_pair &);

std名前空間の引数しか取らない演算子はstdの実装者のみ定義して良いような気がする。
9887:03/11/05 17:43
>>96
それコンパイルしてみた?
9987:03/11/05 17:47
ごめん勘違い死んできます。
private継承だったのね
10087:03/11/05 17:52
あれ?publicでもうまくいっちまった。
あ、勘違いしまくり My_pairのスコープがoperator<<と同じじゃねーか。
もう、−−−だめだめですね。
結局名前のルックアップが出来ないためだったの?
ユーザがstd名前空間の中に何かを追加するのって禁止じゃなかったっけ?
>>102
そんなことやってたら名前空間の意味無くなるしな。
104デフォルトの名無しさん:03/11/05 23:04
とうとうboostを入れたのですが、入れた記念に spirit を使ってみようと意気込んでいます
とりあえず spirit ライブラリーはビルドして、インストールしてライブラリーが無いというエラーはなくなったのですが
それでもシンボルを解決してくれないコードがあります、何が足らないかわかりますでしょうか?
nmake vc7.mak
nmake -fvc7.mak install
でインストールして、以下のコードをコンパイルしたのですが
CppTest error LNK2019: 未解決の外部シンボル
"public: __thiscall boost::reg_expression<char,class boost::regex_traits<char>
,class std::allocator<char> >::~reg_expression<char,class boost::regex_traits<char>
,class std::allocator<char> >(void)" (??1?$reg_expression@DV?$regex_traits@D@boost@@V?$allocator@D@std@@@boost@@QAE@XZ)
が関数 "public: __thiscall boost::spirit::impl::rx_parser<char>::~rx_parser<char>(void)" (??1?$rx_parser@D@impl@spirit@boost@@QAE@XZ)
で参照されました。
といったエラーが 15 個でています、何がたらないかわかる人いたら教えてください。

#include "stdafx.h"
#include <iostream>
#include <boost/spirit.hpp>
#include <boost/spirit/utility/regex.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
boost::spirit::parse( "abc xyz def" , ( boost::spirit::regex_p( "abc" ) >> ',' >> boost::spirit::real_p >> ',' >> boost::spirit::real_p ) ).full ;
return 0;
}
>>102
標準テンプレートの特殊化のみOK
だったと思う。
>>104
ライブラリ追加してないだけじゃないの
>>104
boostのビルドはしたかい?
109104:03/11/06 13:01
>>104
自己レスです
色々インストール方法を試していたらいつの間にか動くようになっていました。
どうも、上手くやらないと lib と dll を取り間違えるみたいですね。
早くインストーラが欲しいです。
ちょうどstd名前空間の演算子オーバーロード問題でハマっていて、質問しにこのスレに来たら
絶妙なタイミングで議論されていて驚きました。

std::setに、独自のクラスをinsertしようとすると問題ないけど、bitsetをinsertしようとするとop<()が
無いと文句を言われる、しかもgcc3系で通らなくてgcc2系とMIPSpro7.3は通るというものでした。
ちゃんと以下を定義しているのに。

template<size_t N>
bool operator<(const std::bitset<N> &rhs, const std::bitset<N> &lhs) { ... }

結局のところ、こいつをstd名前空間に入れるのは間違いで、std::bitsetのようなstd名前空間の
クラスを使う場合は、>>97の言うように独自クラスで包むのが正解と言うことでよろしいでしょうか?

あとコードが通るかどうかは、この場合STLの実装に依存する(insert()定義時のスコープ?)と
考えてよろしいでしょうか?
あるいはコンパイラ間にある名前解決の何らかの違い?
>>110
template <std::size_t N> struct Bitset_cmp
{
    bool operator()(const std::bitset<N> &l, const std::bitset<N> &r)
    {
        return l.to_ulong() < r.to_ulong(); //適当
    }
};
こんなのを定義して、
std::set<std::bitset<16>, Bitset_cmp<16> > collection;
などとすればok
112110:03/11/07 15:34
>>111
なるほど!比較用の関数オブジェクトを作ればいいんですね。
そのためのテンプレートパラメータですよね。勉強になります。
113デフォルトの名無しさん:03/11/07 17:44
マクロのプリプロセッサみたいにテンプレート適用後のソースが見れるようなツールってある?
テンプレートがどういったものなのか C++ を知らなくても雰囲気でもわかるようになる
サイトはありますか?
>>114
そいつは難しい質問だ。ビフテキを食わずに匂いだけで味を当てる
ようなもので、雲をつかむような話だ。
>>116
それは引数の値を変えているだけのようにも見える・・・。
>>117
「テンプレ」なのは間違いないぜ(w
>>114
>>114
様々な型用の自乗関数 in C

int squareInt(int x)
{
return(x*x);
}

long squareLong(long x)
{
return(x*x);
}

float squareFloat(float x)
{
return(x*x);
}

double squareDouble(double x)
{
return(x*x);
}

...(まだまだ続く)
>>114
(続き)
これら(>>119)が C++で多重定義を使うと:

int square(int x)
{
return(x*x);
}

long square(long x)
{
return(x*x);
}

float square(float x)
{
return(x*x);
}

double square(double x)
{
return(x*x);
}

...(名前は共通になったけどまだまだ定義は続く)
>>114
これら(>>119>>120)がさらにC++でテンプレートを使うと:

template<typename T>
T square(T x)
{
return(x*x);
}

…この定義一つで済む。----> ウマー( ゚Д゚)wwwwwww

と、まぁ、これが第一歩w。
>>119
型を意識せずに書けるということ?
普段 Ruby とかをさわっている人にはあまりぴんとこない?
>>122
Rubyは詳しくないが、たしかにSmalltalkのヒトビトは
そもそも型宣言しないわけだから
プログラマに対するインターフェースだけ考えたら確かに「何を今更。」

ただSmalltalkの場合それは実行時にxの型を検査して
必要な*演算の定義を見つけてくるという作業が行われている。

対してtemplateの場合:
実行する前、コンパイル時に検査と適切な*演算の選択は完了するので、
実行時に適切な*演算が見つからないというエラーが起こる心配もないし、
実行時にメソッドを検査したり探したりするオーバー・ヘッドはない。

(ただし実行時まで型が決まらないような場合にはもちろんtemplateは無力なわけだが、
幸い世の中にはコンパイル時までには型が確定する応用も多いのでそれなりに有用。)
>>119-121
そんなのCでは、わざわざ関数使わないマクロ定義で一発解決
>>114
そもそものその考えが無謀だ。C++を使ってないのに知る必要せいはナシでしょう。
>>124
デバッグどうすんの?
>>124
マクロはだめだ、副作用が大きすぎる。
それを回避するのがテンプレートの第一歩ではないか?
テンプレートとマクロは役割被ってるからねえ。
つか、そもそもtemplateの最初の役割は安全なマクロだからな。
>>127
MPL方面に進んでいくにつれ、それぞれに出来ることで
コラボレーションする関係になるけどね。
>>125
まったくだ、templateが噂だけでまだ実装済みコンパイラが手に入らなかった頃に
修論用のプログラムを全部マクロで代用して書いてエラい難儀した。
今でもtemplate関連のエラーメッセージは結構難読だが、
それでもマクロ置換の結果出るエラーから推測するよりはなんぼかいいし、
なによりデバッガがソースレベルでデバッグできるように対応してくれてるのが嬉しい。
131デフォルトの名無しさん:03/11/16 03:24
保全 & age
132デフォルトの名無しさん:03/11/16 03:33
質問です。
いま構造体
struct tag_a
{
 tag_a(int i){idx = i;};
 int idx;
 int data;
};
があったとしてこれをvectorとかlistとかそういったコンテナにぶち込みます。
std::vector<tag_a *> vec;
vec.push_back<new tag_a(1)>;
vec.push_back<new tag_a(2)>;
vec.push_back<new tag_a(3)>;
これをidxでソートしたい場合どうすればよいですか?
bool x(tag_a* a,tag_a* b){return a->idx < b->idx;}
std::sort(vec.begin(),vec.end(),&x);

こんなんでどう?
std::listにstd::sortだと多量のデータの場合遅くなるから
vec.sort(x); の方がいいかも。
つーかstd::sort()はRandomAccessIteratorが必要なんだよな・・・(´д`)
>>133-135
ありがとうございます。
勉強になりました。
>>132
そのコードってリーク起こさないか?
smart_ptr
先を見越せない馬鹿がいるよ
気のせいですw
141デフォルトの名無しさん:03/11/16 17:27
age
142オブジェクト指向促進運動:03/11/16 17:38
IT業界にアージャイル開発とデザインパターンを広めよう!

C言語を使ってかなり苦労したので
その苦労を最小限におさえるために
アージャイル開発、デザインパターンを
多くのプログラマに使って欲しいと思うことがある。

一種の挨拶みたいなものだね。
「なるべく挨拶を心がけましょう。」
「なるべき綺麗な字で書きましょう。」
のように

デザインパターンを使うこと、アージャイル開発することが
プログラマの習慣、常識になってほしい。

なんとか、デザインパターン文化、アージャイル開発文化を押し広げられたら・・・。

IT業界の将来はオブジェクト指向とアージャイル開発が握っています!
業界トークはマ板行け
この間からひっかかってて、週末もうんうんうなってた問題の解決策が、
Effective STLみたらあっさり書いてあった。
いや、この本は一度読んでるんだけど、なんか読み飛ばしてたみたい。
ああー激しく脱力。寝ます。
boost::is_base_and_derivedの話なんだけど
以下のようなコードって通るのね。

//あるヘッダー
struct A {};
struct B ; //前方参照のみ
bool c=boost::is_base_and_derived<A,B>::value; //(1)

//別のファイル
struct B : public A {};
bool d=boost::is_base_and_derived<A,B>::value; //(2)

実行すると c != d になる。
これがコンパイルできちゃうと怖いと思うんだけど。
せめて(1)はコンパイルエラーになって欲しい。
ちなみにVC6 and VC7.1ね。
146デフォルトの名無しさん:03/11/21 11:08
template<HANDLE H> class B
{ };

//B<NULL> b; // こっちはOKなのに
B<INVALID_HANDLE_VALUE> b; // こっちはダメ

上記のようにテンプレート引数がNULLの場合はコンパイルが通るのですが
INVALID_HANDLE_VALUEの場合は
 error C2964: テンプレート パラメータの式が不正です。
と怒られます。
B<reinterpret_cast<HANDLE>(-1)> b;
と書いても同様でした。
エラーになる理由がわかりません。何故でしょうか?

VC++6.0 SP5
つーか、C++BuilderX付属のBCC5.6.4及びgcc(mingw)3.2では
B<NULL> b;すら通らないが。
>>146
VC7.1なら通るね
149146:03/11/21 12:44
template<int T> class B
{};

B<0> b1;
B<-1> b2;

これは良くて>>146がダメな理由が謎です。
いったいなんなんでしょう?
150146:03/11/21 12:54
template<int* T> class B
{};

B<0> b1;
B<reinterpret_cast<int*>(-1)> b2; // error C2964

としたらエラーになりました。謎が深まりました。
151名無し:03/11/21 12:54
こういうのもあるんだ。。
http://palette.daa.jp/FlashPalette/Page/seo.htm
>>150
なぞというかVC6.0がへぼいからでは
>>150
エラーメッセージ読んでますか?
>>150
VC7.1では通るぞ。VC6.0のせい。
>>154
拡張じゃないの?
規格(14.3.2)外だよ。
156146:03/11/22 00:04
>>153
読んでます。「テンプレート パラメータの式が不正です。 」ですが
どう不正なのかがわかりません。
テンプレート引数って定数じゃないといけませんよね。
reinterpret_cast<int*>(-1)
って定数ではないのですか?
引数がintだとどんな値でも良くて、int*になると0以外の値がダメというのが納得できません。
どう解釈すればいいのか…
>>155
ありゃ本当だ。gcc3.3.1で試すと、0すら通らない。

reinterpret.cpp:11: error: could not convert template
argument `0' to `int*'
Learn/Learn3/reinterpret.cpp:11: error: ISO C++ forbids declaration of
`b1' with no type
reinterpret.cpp:12: error: `0ffffffff' is not a valid
template argument
reinterpret.cpp:12: error: it must be the address of an
object with external linkage
reinterpret.cpp:12: error: ISO C++ forbids declaration of
`b2' with no type
reinterpret.cpp:11: warning: unused variable `int b1'
warning: unused variable `int b2'

Execution terminated
>>156
> テンプレート引数って定数じゃないといけませんよね。

定数式、または外部リンケージを持つオブジェクト・関数(およびそのアドレス)
です。

> reinterpret_cast<int*>(-1)
> って定数ではないのですか?

ちがいます。

> 引数がintだとどんな値でも良くて、int*になると0以外の値がダメというのが納得できません。

現行の規格ではヌルポインターも認められません。
VC6は中途半端
VC7.1は激しく拡張
gccは規格厳守
>>158
>> reinterpret_cast<int*>(-1)
>> って定数ではないのですか?

>ちがいます。

どうちがうの?
>>159
定数式
定数式なら OK じゃないのかよぉと思ったので調べてみたら

- an integral constant expression of integral or enumeration type

なのね。整数じゃないとだめなのか。
おいおまいら、聞いてください

無駄に一時オブジェクトを生成する書き方の例として、
std::string s0, s1, s2, ..., sn;
s0 = s1 + s2 + ... + sn;
なんてのが例に挙げられることがあるが、例えば、
class My_string_l;/* 左辺値 */ class My_string_r; /* 右辺値 */
として、
My_string_r operator+(const My_string_l &, const My_string_l &);
My_string_r operator+(My_string_r &lhs, const My_string_l &rhs)
{/* lhs+=rhsの意味を持つ実装 */}
みたいにすれば、上の例の一時オブジェクトを一個に減らすことができるよな?

これを一般化してジェネリックに(stringをパラメータ化して)実装できたら面白いと思うがどうだろう。
>>162
面白いと思うが、
 s0 = (s1 + s2) + s3;
の s1+s2 が返すのはMy_string_rの一時オブジェクトだから、
非const参照(My_string_r&)で受けられない。つまり、
 My_string_r operator+(My_string_r &lhs, const My_string_l &rhs)
に渡せない。やるなら
 My_string_r operator+(My_string_r lhs, const My_string_l &rhs)
にして、My_string_r 型のコピーを auto_ptr っぽく実装するくらいになるのでは。

つか、Expression Template で十分。
ttp://www.kmonos.net/wlog/28.php#_0029030612
つぅか
std::string& operator<<(std::string& lhs, const std::string& rhs);
でも定義すればいいだけじゃないか? +=で問題なのは右結合ぐらいだろ。
>>163
thanx!勉強にナターヨ
expression templateも面白そうだ。

>>164
なるほど、なるほど。
op<<はもうシフト演算子じゃなくなっている気がするな。
あの、初歩的なことかもしれませんが、
テンプレートクラスを引数に取るテンプレート関数を、そのテンプレートクラスの中でfriend指定する方法で、
(ややこしい...)試行錯誤の結果以下のようにすればコンパイラが満足することが判りました。

template<typename T>
class Foo {
 template<typename _T, typename U>    // _Tはテンプレート引数の二重宣言エラーを防ぐため
 friend void func(const Foo<_T> &, const U &);
};

template<typename T, typename U>
void func(const Foo<T> &f, const U &u) { ... }

これは正しい書き方なのでしょうか?動いているから正しいのかもしれませんが、
friendして欲しいテンプレートクラス「のみ」引数に取る場合のオーソドックスなやり方...

template<typename T>
class Foo {
 friend void func<T>(const Foo &);
};

template<typename T>
void func(const Foo<T> &f) { ... }

とあまりに見た目が違うので違和感を覚えます。
なおgcc3でコードは通っています。
これじゃだめ?

template< typename T >
class Foo
{
 template< typename U >
 friend void func( const Foo& , const U& );
};
template< typename T , typename U >
void func( const Foo< T >& f , const U& u )
{
}
う〜ん。
たしかに>>166が提示した問題は狐にだまされたような胸にしこりの残る問題だな。
俺としては単にコンパイル時間の違いだけのような気がするのだけど
>> 145
こんなのでどうでしょう.いいコードじゃないけど.

namespace test {
template <typename A, typename B>
struct is_base_and_derived : private B {
static bool const value = boost::is_base_and_derived<A, B>::value;
};
170145:03/11/25 01:32
>>169
エラーにするなら他にsizeof(B)を
is_base_and_derivedにまぜるとかってのも
ありだと思います。

is_base_and_derivedをみるとLokiと違って
func(A*)とfunc(...)でディスパッチしていて
Bが定義されてなくてもfunc(B*)がfunc(...)を
見に行ってしまうみたいです。但し、Lokiみたいに
func(A)とfunc(...)でBが未定義でも、func(B.)は
func(...)を見に行ってしまうようです。

VCのコンパイラバグ?C++の仕様?
いずれにしてもboostはなんでエラー
にするようにしなかったでしょう...。
ただの抜けだと思う。
提案するのもありでしょう。
172169:03/11/25 22:46
>>170
sizeof(B) 忘れてた...
Bが_宣言_されていれば,Bへのポインタとか,参照とかは
_定義(define)_されてなくても使えますよね.
あと,Bを引数にとる関数の_宣言_もできます.
だから,func(...)を見にいくのはC++的に正しいと思います.
gcc 3.3でも同じ結果になりました.

#include <boost/static_assert.hpp>
class incomplete;
int accept_incomplete(...);
// incompleteの定義はいらない
incomplete return_incomplete(incomplete);

int main() {
incomplete* p = 0;
BOOST_STATIC_ASSERT(sizeof accept_incomplete(p) == sizeof (int));
}

>>171
"Types T and U must not be incomplete types." ってあるんだけど,
なんでエラーにならないんでしょうね.
173166:03/11/26 00:48
急な出張でレスが遅れました。

>>167の方法は真っ先に試したのですが、リンク時エラーになります。
テンプレート関数を具体化したシンボルが見つからないと怒られます。

ld32: ERROR 33 : Unresolved text symbol "func(const Foo<double*>&,const int&)" -- 1st referenced by test22.o.
こんな感じ。

gcc3.2.2(FreeBSD 5.1)およびMIPSpro7.3でそうなるんだけど、今日試したら
gcc2系では通るなぁ。VCは環境がないので判りません。

で、
func<double *, int>(Foo<double *>(), 123)
などとパラメータを明示すると、こんどはfunc()がfriendになってくれません。
>>173
クラス内に定義を書き込めば通るみたい。

template< typename T >
class Foo
{
 template< typename U >
 friend void func( Foo , U ){}
};
int main()
{
 func( Foo<double*>() , 0 );
}

逆汗みるかぎり、定義された関数は
void func<int>( Foo<double*> , int );
ということで、
void func<doubel*,int>( Foo<double*> , int );
ではなかった。
>>166
その書き方だと、 func のすべてのインスタンスが Foo<T> の friend になってしまう。
T と _T が違っていても friend になってしまうので、やりたかったことと違うのでは?
vectorってちゃんと繋がってる配列を生成してるんですか?
177デフォルトの名無しさん:03/11/27 23:46
上げ
>>176
る。
最新の規格ではvectorの中身はちゃんと配列になってないと
いけない、と規定されてるし、古いコンパイラ付属のライブラリでも
そうなってないのは見たことがない。
dequeはちゃんと繋がってなかったりする
vectorをなんで連続を強制にしたんだろう。
メモリ連続を保証するarrayクラスみたいなのを
別途作るって手もあってもいいような気がするけど
stlportのデバッグモードみたいな使い方もできるし。
拡張可能でCのAPI互換なのが便利だからだろ
182176:03/11/28 08:31
>>178
>>179
送れてすいません。レスありがとうございました。
いや、だからC API互換な拡張可能配列は別途作ればって意見。
list/deque/vector等の実装の自由度は残しておいたほうが
良いようなきがするんだが...。
>>183
連続に「した」んじゃなくて皆最初から連続のつもりだったけど
規格に書き忘れていたってのが真相。
>>178
>>184
最新の規格とか、書き忘れられていた規格ってどの規格?
International Standard 14882:1998 - Programming Language C++
以外にC++の規格ってあるの?
「正式な追加事項」があるんだよな確か。
どこだっけな。
>>185
14882:2003
>>185
C++98 は Technical Corrigendum 1 (vectorの連続性とかの修正の追記) を反映した
http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=38110&ICS1=35&ICS2=60&ICS3=
に置き換えられた。
http://std.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html
こういうものは読んでますか?

あと、boost-1.31はまだかしらん、、
190GETクラスメンバ:03/11/30 13:45
テンプレートに関連した質問です。
typeinfoクラスで、実行時にclassの名前を取り出せますが、
同じように、実行時にメンバの一覧を取得することはできないものでしょうか?
テンプレートクラスで、渡されたクラスのメンバ(と型)の一覧が得られる仕組みはないのでしょうか?
知ってる人、教えてください。
gccなら出来たような気がした。
192GETクラスメンバ:03/11/30 14:10
gcc(g++) 3.2 を使っているので、OKっす。
何か、断片でも思い出して頂けませんか??
コンパイル時にtypeofで型が得られるけど
来月のInterfaceでBoostの特集やるみたいね。
195GETクラスメンバ:03/11/30 14:54
情報さんくすです。
でも、型でなく、メンバ一覧がほしいんですよー。
196デフォルトの名無しさん:03/12/02 16:57
デザインパターンをテンプレートクラスにしようと思うのですが
既にありますか?
>>196
Lokiにいくつか。
>>197
見てみます。ありがとうございました。
Modern C++ Designぐらい買おうよ。
200デフォルトの名無しさん:03/12/02 22:34
template<typename T, int N>
struct A
{
typedef T type;
enum{value = N};
};

って感じのA<t, n>を持つタイプリスト(70要素程)をつくって、
typeで検索したりvalueを足していったり、
あれこれやるライブラリを作ってみました。

が、いざいろんなとこで用いてみると死ぬほどコンパイルが遅いです。

templateメタプログラミング(?)をする時に用いる高速化テクニックがあったら
教えて下さい。
>>200
boost/libs/mpl/doc
202デフォルトの名無しさん:03/12/03 01:35
>>201
遅延評価はやってます。
別に何か無いでしょうか?

boostの無いコンパイラなので、一からmplもどきを作ってて結構面白かったんですが、
本格的に使おうとすると、実はあまり実用ではないのかな?と感じています。
もちろん軽い使い方ならかなり便利だとは思いますが。
pair<string,int>を持つリスト(70要素程)をつくって、
stringで検索したりintを足していったり、
あれこれやるライブラリを作ってみました。

が、いざいろんなとこで用いてみると死ぬほど遅いです。

プログラミング(?)をする時に用いる高速化テクニックがあったら
教えて下さい。

>>202
実装晒さないと答えようがないだろ。
>>203
なぜmap(hash_map)じゃなくてlist?
std::ifstream でオープン済みのファイルのサイズを得る方法ってありますかね?

いまは、
std::vector<char>vect;
std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::back_inserter(vect));

とやって、
vect.size()
でサイズを持ってきているのですが、まどろっこしくて。
in.seekg(0,std::ios::end).tellg()
207205:03/12/06 21:10
>>207
>まどろっこしいどころの問題ではない。根本的に間違いです。
うるさい。そんなこと言われないでもわかってるわ。(` д´メ) ノコラ!
電波?
非常に珍しい誤爆だな
誤爆じゃなきゃ>>208
というか
>>205の無理矢理な方法でも
copyより範囲メンバ関数insert
範囲メンバ関数insertより二項コンストラクタを使うべきだな。
このスレ的には Effective STL を読むことを勧める。
ファイルサイズを求める方法は書いていないがw
>>206
OSにもよるが、例えばWindowsではsize_tがunsigned intのtypedefだったり
するから4G以上のファイルのサイズを知る時に不都合な事がある。この
場合はGetFileSize()を使わなければならない。VC7では対策されているよ
うだが。
212デフォルトの名無しさん:03/12/11 22:13
つい最近STLの勉強を始めたものですが、木構造のコンテナを作ろうと
していて、質問があります。

親を指すなにかと値のpairをvectorにいれて実装しようとしています。親を指す
なにかをこのpairをさすiteratorにしたいんですが、次のように再帰的になって
しまい書けません。

vector<pair<vector<pair<vector<pair<..., T>, T>::iterator, T>>>>

どのようにしたらいいんですか?
set とかmapではいかんの?
車輪の再発明カコワルイ。
214デフォルトの名無しさん:03/12/11 22:17
再開発だYO!
setやmapは汎用的な木構造ではないと思うが。あくまで連装配列専用。
>>215
知ったかカコイイ!!
>>216-217
…アフォ?
>>212
struct pair;
typedef std::vector< pair > container_type;
struct pair
{
 typename container_type::value_type parent;

↑で通るコンパイラは多いかもしれない
けど、実際は未定義。
>>218
言わずもがな。

>>212
pair 使わない。

template <typename T>
struct node
{
  T val;
  typename std::vector<node<T> >::iterator parent;
};

あと、そもそも木を作る場合には各 node を連続メモリ領域にとる必要ないから、
vector より list 向きだと思うが。
boostの使用法に関する質問はこちらへ投じてよろしいのでしょうか?
環境はWindows98上でフリーのbcc5.5.1(英語版)です。

タプルを使おうと<boost/tuple/tuple.hpp>をincludeしただけの
ソースファイルをコンパイルすると、以下のようなエラーが出ます。

Error E2434 c:\lib\boost-1.30.2\boost/tuple/detail/tuple_basic.hpp 158: Template declaration missing template parameters ('template<...>')
Error E2238 c:\lib\boost-1.30.2\boost/tuple/detail/tuple_basic.hpp 158: Multiple declaration for 'element<N,T>'
Error E2344 c:\lib\boost-1.30.2\boost/tuple/detail/tuple_basic.hpp 143: Earlier declaration of 'element<N,T>'

該当部分を見ると、
156 template<int N, class T>
157 struct element
に対する特殊化
142 template<int N, class T>
143 struct element<N, const T>
が多重定義と見なされているように思えるのですが……。

http://boost.sourceforge.net/regression-logs/cs-win32.html
こちらでもtuple_test_benchはfailになっていますが、
このような単純なエラーの出方ではないようですし、どうにもわかりません。

コンパイルオプションの変更やマクロ定義などでどうにかなるのでしょうか?
解決法、あるいは解決は不可能とご存じの方、どうか教えてくださいませ。
一応、同じ質問都やりとりを
http://lists.boost.org/MailArchives/boost-users/msg03890.php
こちらで見つけたのですが、
特殊化部分をコメントアウトするのような
元のソースに手を加える方法はできるのなら避けたいのです。
(他のコンパイラでも同じファイルを共有して参照しているので)
特殊化部分を

#ifndef __BORLANDC__

#endif

みたいなのではさみ込むのは?bcc使ったことないから知らんけど。
原理的には他のコンパイラから参照されても大丈夫だと思うが。
あ、それいただきます。
こんな時間にありがとうございます。

しかしこれくらいの措置だったら
boost側でやっていそうなものですけど……。
でも現状に対してはその療法で充分です。

どうもありがとうございました。
しかし>>223では、他のコンパイラでは問題ないだろうけど、
BCC限定で妙な副作用が出そうな悪寒もする罠。
>>206
tellg の戻り値は streampos 型(あるいは ios::pos_type)
だが、これは fpos<> 型であって整数型ではない。

>>211
ストリームのオフセット位置を保存するには
size_t ではなく、streamoff 型(あるいは ios::off_type)
を使う。環境にもよるが size_t が 32bit でも
off_type は 64bit だったりする。

規格書を見ると fpos<> から整数型への変換は無いが、
2 つの間の減算は定義されていて、その結果は
streamoff 型になる。なお streamoff 型は符号付き整数型。

というわけで、最初と最後の tellg の結果を
減算してサイズを求めるのが移植性のある方法。
227デフォルトの名無しさん:03/12/16 19:11
オーバーライドした関数かどうか見分ける方法ってないですかね?
class Base
{
virtual void func() { ... }
} ;

class MyClass1 : public Base
{
} ;
class MyClass2 : public Base
{
virtual void func() { ... }
} ;

is_override<Base>( MyClass1::func ) == false
is_override<Base>( MyClass2::func ) == true

見たいなのが欲しいんですが・・・
>>227
ちょっと興味深いので背景を少し説明してもらえるだろうか。。。
興味本位なので、面倒ならいいです。
漏れもキボンヌ。
230デフォルトの名無しさん:03/12/16 22:37
>.227
std::cout << (typeid(MyClass1::func) != typeid(Base::func));
std::cout << (typeid(MyClass2::func) != typeid(Base::func));
これじゃいかんの?
なるほど。>>230氏のをコンパイル時バージョンにしてみた。

template<typename T1, typename T2> char helper(T1,T2);
template<typename T> char (&helper(T,T))[2];
#define is_override(mf1, mf2) (1 == sizeof(helper(mf1,mf2)))

cout << is_override(&MyClass1::func, &Base::func);
cout << is_override(&MyClass2::func, &Base::func);
>>231の解説キボンヌ。特に2行目。
helperがテンプレートの特殊化を使って型判別し、
型が異なればchar、同じならばchar[2]を返す、
したがってそのsizeofは前者は 1 後者は 2 になるってことでしょう。
sizeofとマクロを使わずに改良できないかな
234デフォルトの名無しさん:03/12/17 00:52
皆さんにお聞きしたいのですが, 例えば Expression Template を使って
実装した行列クラスのテストをする場合, どういう風にやるのがいいのでしょうか ?
テンプレートを使うとすべてのコード (というか状況) をテストすることが非常に困難だと
思うのですが.
template<typename T1, typename T2>
struct is_overridden_ {
  enum { value = 1 };
};
template<typename T>
struct is_overridden_<T,T> {
  enum { value = 0 };
};

template<typename T1, typename T2>
is_overridden_<T1, T2> is_overridden(T1, T2) { return is_overridden_<T1, T2>(); }

is_overridden(&MyClass1::func, &Base::func).value

こんなのは没ですか? 最後の.valueが激しくカコワルイ。
>>235
そんなことするぐらいなら

template<typename T1, typename T2> int is_override(T1,T2) {return 1;}
template<typename T> int is_override(T,T) {return 0;}

の方がマシなのでは?
237236:03/12/17 01:47
>>235
>>236の発言は
>>231
> コンパイル時バージョンにしてみた。
を受けたもの。
238235:03/12/17 14:11
>>236
それはコンパイル時に評価されないだろ。と思って
自分のも試してみたら両方ともダメだった_| ̄|○
鬱氏

sizeofとマクロを使わずに出来ますか?お願いエロイ人。
>>233
ああ、関数のプロトタイプなのね。ありがd
template<typename T1, typename T2>
bool is_override(T1,T2) {return true;}
template<typename T>
bool is_override(T,T) {return false;}

int main(){
cout << is_override((&Base::func) ,(&Base::func)) << endl;
cout << is_override((&MyClass1::func),(&Base::func)) << endl;
cout << is_override((&MyClass2::func),(&Base::func)) << endl;
return 0;
}

結果
0
0
1

これが一番スマートだ。問題ないような気がするけど・・・
>>240
既出
要するに>>231が一番ゴミを増やさずに一番良い方法だね
んだんだ。
cout << is_override((&OtherClass::otherMethod),(&Base::func)) << endl;
>>244
#include >>231
#define is_differently_defined is_override
で。
少し前にC++スレで話題になってた上限つきvectorを
実装してみたんだが、激しく面倒だな。
単純なコンテナのはずなんだが。
ライブラリ書いてるヤシらはいつもこんなことやってるのか…
それとも俺のレベルが低いのかな。
>>246
どのレベルまでC++標準のコンテナ要求仕様を実装するのかにもよりそうだが・・
>>247
俺は規格書を持ってないから、禿3版のvectorの項を見ながら、
載ってるメンバ関数の内意味を為さないもの(reserveとか)を除いて
書いてみた。標準の定めるコンテナの定義には適わないんじゃないかな。
>>248
公開キボン
template< typename T , std::size_t N >
class limited_vector : private std::vector< T >
{
 typedef std::vector< T > base_type;
public:
 limited_vector() { reserve( N ); }
 void push_back( T const& x ) { if( size() < N ) push_back( x ); else throw std::bad_alloc(); }
 ...

こんな方針で行けば楽勝かと思ったけど、
必要なインターフェースを提供するだけでもめんどくさいな。
何で継承なんだ?しかもプライベート
vectorのデストラクタは仮想関数じゃなかったような気がする。
>>252
privateでアクセスが禁止されているので大丈夫

その前にvectorの上限ぐらい簡単に記述できるんだから
その場所場所のところでチェックしろよって思う
仮想デストラクタはもちろん
resizeやreserveも提供しないしpush_backの振る舞いも変えてしまうんだから
実装のみを受け継ぐprivate継承は適切だと思うが。

それより俺はアロケータのサポートがない方が気になる。
確かにsize_t Nとcapacity()の部分は冗長だな。
まあそういう部分まで切りつめたけりゃ結局一から作れってことになるんだが
queueやstackみたいにコンテナアダプタで作るのが妥当って気もするが。
boost:arrayを抱え込んだ方が楽じゃないか?
>>257
サイズが変えらんないから無理。
>>249
http://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/readres.cgi?bo=lounge&vi=999294620&res=117
一応テストはしたが、あまり信頼しないでくれ。

誰か、holderのまともな奴を考えてくれないかな。
>>258
上限付きだからいいと思ったんだが……上限は可変なのか……じゃ確かに無理だな。
上限とサイズは違うんじゃないか?
>>259
boost::aligned_storage
と思ったけど、まだリリースには含まれてないのか。
>>259
private継承しててもreinterpret_castや(std::vector<T>*)とか使って
キャストされてしまったらいけないから素直にメンバにvectorを抱え込ませた
ほうがいいと思う。
>>263
>>259のどこにprivate継承がある?
reinterpret_castは他にもひどいこといろいろできるからいまさら
心配しなくてもよし
>>262
ありがとう。感動したよ。
mpl読めないから微妙だけど、やっぱりunionに
いろんな型を放り込むのが基本みたいだな。
267263:03/12/26 11:47
>>264
250みたいにしてるのかとDLせずに勝手に思い込んでた
明けまして、おめでとうございます。
interfaceでtemplateの特集してたけど
あんまり反響無いな。
interfaceでなぜにtemplateなんだろう。
>>269
俺もだいぶ前に見たけど10P足らずで表面なぞるだけだったんで
いまさらここで話題にするまでもないと思った。
無理に boost まで出さない方が身のある記事になったんじゃないのって感じ。
STLの記事はまあまあだったと思う。
273名無しさん@Vim%Chalice:04/01/04 09:43
>>271
ハゲ同。boostの記事なんか薄っぺらいだけの無意味なページ稼ぎにしか見えなかった。
>>272
STLの記事の著者は CINT の人だよね。

C言語の記事で、リストについては侵入的なコンテナの方が
いい場合もあるんだって書いてあったけど、STLだと侵入的
リストってないよね。boostにはあるんだっけ?
>>274
boost は intrusive_ptr ですな
>>274
> 侵入的リスト
面白そうだなあ。boost::iterator_adaptor 使って
侵入的イテレータまでなら作れるかも。

>>275
それは侵入的スマートポインタであって、コンテナには関係ないと思う…。
277274:04/01/05 20:40
>>275

むむ素早い。どうも。
でも intrusive_ptr には、記事に書かれてる侵入的リストの
利点 (iterator ではなくオブジェクトへのポインタを元に O(1)
でリストから erase できる) は、ないように思えるんだけど
気のせい?
確かに、
STLコンテナのメンバ関数が
アルゴリズムと同じほど豊富な機能を提供してくれるわけじゃないから
イテレータを高機能にしていくつかの処理をグローバル関数から呼べたらって思うことはあるなあ。
list は安定ソートは持ってても nth_element や partion に当たるものはないし。
メンバ関数は概して xxx_if 系とか集合的な演算とか関数オブジェクトと組み合わせる処理は特に弱いし。

#list を使うときは途中で切ったり入れ替えたりマージしたりって
 結構明確な目的があることが多いと思うけど。
279sage:04/01/05 23:55
list に nth_element がないのは、むしろ STL の
美しいところだと思うが…
280デフォルトの名無しさん:04/01/07 04:35
class T3 を typename T3 にするとコンパイルは通らないのですが、
class T3 だと今度は
T3を指定せずにコンパイルできてしまうのですが、こういうものなのでしょうか?

template <typename T1,typename T2> struct Q1{};

template <typename T1,typename T2 = Q1<T1,class T3> > struct B
{ typedef T2 type; };

#include<typeinfo>
#include<iostream>
int main()
{ std::cout << typeid(B<int>::type).name() << std::endl; }
>>280
テンプレートパラメータはclass,typenameどっちでもいいけど、
テンプレートパラメータのテンプレートパラメータはclassじゃないとダメ。

>T3を指定せずにコンパイルできてしまうのですが、こういうものなのでしょうか?
コンパイラなに使ってますか?
>>281
その根拠は?
vc7.1動作確認済み。
template <typename T1,typename T2> struct Q1
{
  typedef T2 type2;
};

template<class T=class _1,class U=class _2,template<typename,typename>class TQ = Q1>
struct test
{
  typedef typename TQ<T,U>::type2 type;
};
#include <iostream>
#include <typeinfo>
int main()
{
  test<> t;
  std::cout<<typeid(t).name()<<std::endl;
return 0;
}
283280:04/01/07 07:51
>>281,282
ありがとうございます。
VC7.1、VC6、GCC3.3.1で確認しました。(実行結果はバラバラでした)
これからはtemplateのデフォルトの型を指定するときには
型がちゃんと確定するように気をつけようと思います。
285名無しさん@Vim%Chalice:04/01/14 23:35
Let's boost で見付けただけなんだが、
ttp://tinytl.sourceforge.net/
なかなかいい感じだ。確かにサンプルのコンパイルはboostの三倍ぐらい早いな。
ただコードが複雑になって来るとインクルードの時間の割合いは減ってくるからどこまで効果あるかは微妙だけど。
まぁソース読むのにはこっちのが良さ気なだけでも十分面白くてありがたいけど。
286デフォルトの名無しさん:04/01/15 18:38
>>285 って何なの?英語が分からんよ。教えてエロい人.
overviewくらい読めよ。
Boost と置き換えられる軽くて実際に使えるテンプレートライブラリ、らしい。
こういうのは感心しないね。サブセット作って
コンパイルも軽いですとかいうの。boostは
ハードウェア業界からの要請でわざと重くて重厚な
ライブラリを作ってるっていうのに。
やっぱりハード売るためにboostはわざとコンパイルも動作速度も糞重くしてたのか。
         ナ ゝ   ナ ゝ /    十_"    ー;=‐         |! |!
          cト    cト /^、_ノ  | 、.__ つ  (.__    ̄ ̄ ̄ ̄   ・ ・

ミミ:::;,!      u       `゙"~´   ヾ彡::l/VvVw、 ,yvヾNヽ  ゞヾ  ,. ,. ,. 、、ヾゝヽr=ヾ
ミ::::;/   ゙̄`ー-.、     u  ;,,;   j   ヾk'! ' l / 'レ ^ヽヘ\   ,r゙ゞ゙-"、ノ / l! !ヽ 、、 |
ミ/    J   ゙`ー、   " ;, ;;; ,;; ゙  u ヾi    ,,./ , ,、ヾヾ   | '-- 、..,,ヽ  j  ! | Nヾ|
'"       _,,.. -─ゝ.、   ;, " ;;   _,,..._ゞイ__//〃 i.! ilヾゞヽ  | 、  .r. ヾ-、;;ノ,.:-一'"i
  j    /   ,.- 、  ヾヽ、 ;; ;; _,-<  //_,,\' "' !| :l ゙i !_,,ヽ.l `ー─--  エィ' (. 7 /
      :    ' ・丿   ̄≠Ξイ´,-、 ヽ /イ´ r. `ー-'メ ,.-´、  i     u  ヾ``ー' イ
       \_    _,,......::   ´゙i、 `¨ / i ヽ.__,,... '  u ゙l´.i・j.冫,イ゙l  / ``-、..- ノ :u l
   u      ̄ ̄  彡"   、ヾ ̄``ミ::.l  u   j  i、`ー' .i / /、._    `'y   /
              u      `ヽ  ゙:l   ,.::- 、,, ,. ノ ゙ u ! /_   ̄ ー/ u /
           _,,..,,_    ,.ィ、  /   |  /__   ``- 、_    l l  ``ーt、_ /  /
  ゙   u  ,./´ "  ``- 、_J r'´  u 丿 .l,... `ー一''/   ノ  ト 、,,_____ ゙/ /
        ./__        ー7    /、 l   '゙ ヽ/  ,. '"  \`ー--- ",.::く、
       /;;;''"  ̄ ̄ ───/  ゙  ,::'  \ヾニ==='"/ `- 、   ゙ー┬ '´ / \..,,__
、      .i:⌒`─-、_,....    l   /     `ー┬一'      ヽ    :l  /  , ' `ソヽ
ヾヽ     l      `  `ヽ、 l  ./  ヽ      l         )  ,; /   ,'    '^i
291デフォルトの名無しさん:04/01/16 18:42
>>289
gccにpch機能が内蔵されれば糞重いboostもきっと軽くなるから
それまでの辛抱。それまでVC7.1でも使っていよう。
今時PCも買えないような貧乏人がプログラミングしてるんですか?
P4EE使いでつが何か?
>>292
君の書いた1万行程度のプログラムだったらPC換えれば早くなるけどねえ。
そんなしょぼいプログラムじゃないのよ。
>>294
金があるなら、マシンを 10 台ぐらい並べて分散コンパイルしとけ。
スレ違いうざいよ
だからP4 3GOver使ってもBoostは重いっつってんだろ(゚Д゚)ゴルァ!!
298デフォルトの名無しさん:04/01/17 03:23
〜(・∀・)〜
今時P4かよw
だから C3PO 使ってもBoostは重いっつってんだろ(゚Д゚)ゴルァ!!
>>299
あー言っとくけどx86-64は死ぬよ。
>>295
君の書いた1万行程度のプログラムだったらPC換えれば早くなるけどねえ。
そんなしょぼいプログラムじゃないのよ。
>>302
1万行以上のソースを 1 ファイルに書いてるのか? それは設計腐ってるとしか……。

ファイルを適切なサイズで分割してあれば、複数のマシンで分割コンパイルすることで、
ほぼマシン数に反比例した時間でコンパイル終わるようになるぞ。分散コンパイルを
サポートするソフトも何社かから出てるから、金で解決しとけ。
>>303
レスちゃんと嫁。おまいの妄想だけで話を進めんな。
あとスレ違いだ。氏ね。
>>301
Intelもx86-64に参入すると言われているのに、どうやったらそんな話になるんだか。
>>304
> レスちゃんと嫁
どれを読めと。縦読み?
C++テンプレートはexportキーワードがサポートされていないコンパイラ(ほとんど)だと
ヘッダ中に全ての処理を書かなければいけない。
プリコンパイルヘッダを使っていなければ
ソースファイル1つにつき数百のヘッダが少なくともパースされる。

という事では。
どうでもいいけどexportをサポートしてるコンパイラって、
リンク時にコード生成もするのか?
Comeuのドキュメントとか見てるとそんな感じっぽいな。
使う側は宣言だけだからリンク時にインスタンス化するほかない。
分割コンパイルする場合はコンパイル時に--exportオプションとかいるみたいだし。
>>307
それと >294 の
> 君の書いた1万行程度のプログラムだったらPC換えれば早くなるけどねえ。
このつながり謎だ。

CPU 速くすればコンパイル時間は短くなるし、翻訳単位ごとにプリプロセスとコンパイル作業を
複数マシンに分散させれば、やっぱりコンパイル時間短くなるぞ。
>>309
テンプレートをバリバリ使ったC++ソースのコンパイルで
ちゃんと効果が出るような分散コンパイルができる環境ってあるの?
プリコンパイルヘッダの更新のタイミングが重要だと思うけど。
なんだかJava厨が湧いてきたみたいだな。
template知らんのだろうか
>>309
頭おかしいんだろ。
放置しておけ。
>>311
たぶん、知っていても今までexportが必要じゃなかった。
そして、これからも。そんなレベルの方々なのでしょう。
>>311
確かに標準C++のexportキーワードは無理目の仕様。C++の
type safe linkage だって既存のリンカがそのまま使えるように
との配慮だったのに、exportをまともに実現しようとしたらリンカ
に大改造を施さなければならない。

まあ前者はC++が早急に広まるようにという意図かもしれなかっ
たから、C++が十分に拡散した今、exportをまともにサポートして
もいい時期に差し掛かっているのかも。
315デフォルトの名無しさん:04/01/18 20:32
2つの文字列を入力し、数値化したものを比較、勝敗を表示する。但し文字列と数値データは構造体で扱う。又、文字列、→数値変換はmoji_ten()関数を処理する。準備するもの@構造体定義より
{文字列列用・・・char型(20バイト以上)
{点数用......int型A数値変換はmoji_ten関数を使用する。名前を入力させ攻撃用文字列と防御用文字列と体力など攻撃力と防御力設定する。
画面のイメージ↓
/////////////////////////////
/player1の名前を入力して下さい→
/player2の名前を入力して下さい→
/player1の武器を選んでください→
/player2の武器を選んでください→
/player1の防具を選んで下さい→
/player2の防具を選んでください→
/ 戦闘開始
/ player1体力500player2体力500
/  1ターン目player1に100のダメージplayer2に200のダメージ
/  2ターン目player1400のダメージplayer2に300のダメージ
/     引き分けです。
///////////////////////////////////////////
こんな感じで表示させたいです。player1かplayer2のダメージはランダムであと引き分けありで
表示させたです。
最初のこんなしかわりません。w
#include
struct BATTLER
{
char name[20]
int ten
};
void moji_ten(struct BATTLER *);

void main(void)
{
次からよくわりません教えてください。文字列バトラーの応用です。お願いします。
なんで template なの〜
>>315
マルチポスト
>>315
マジうけたぞーーーーーー。
ああ〜泪がちょちょぎれる
そろそろboost内でもテンプレートライブラリネタが尽きたかんじ?
>>319
まだまだ。ここ数ヶ月に出たネタだけでも、Notusにfusionにpqsに
indexed_setにxpressiveにNamedParamsにTaggedTypeに・・・
むしろもうなにやってんだかさっぱりわかんない。>Boost
NamedParamsはもう大分だつような
Boost初心者の漏れにC++erとしてたしなみといえる
クラスを列挙してくれ。
boost::regex あたりから入るのはどうかね?
標準の補完としての functional と compose
それ以外なら format, smart_ptr だな。
何を作るにしても役に立つ
俺的よく使うもの
shared_ptr, scoped_ptr,
lexical_cast ,
function, bind ,
array,
optional( てか、これって内部でオブジェクトのコピーしてるのね。重いやつにこれ使うのよくない?)
timer( アルゴリズムのテストするときとかに便利)
thread( dll作成しないといけないのがあれなんで、一部変更してstaticリンクしてみたり。)
>>325
composeはbindにまとめられるので死亡予定です。
とりあえずnoncopyable
boost::threadとかregexとか、あそこらへん
staticリンクで使えるようにならんかな・・・。
バージョンアップするたびにDLL作るのめんどい。

ところで、vc6でb-jam使ってビルドした場合、bad_alloc投げるようになっているんでしょうか?
>>329
いや、boost::regexは普通にスタティックリンクライブラリ使えるだろ。
331329:04/01/22 22:40
すまん、regexはできたな、スタティックリンクも・・・。
おいらが確認したときは明示的にハンドらをセットしない限り投げなかった。
ヒープの管理はVCのコードを使ってるっぽい
333323:04/01/23 03:20
レス遅れてすいません。(;´Д`)
列挙されたクラス早速みてみます。
ありがとうございました。
334329:04/01/23 08:11
>>332
誠にもうしわけござまいませんが、b-jamでビルドするときに
明示的にハンドラををセットする方法を教えていただけないでしょうか?

普段はboostを使う方で、new 書き換えてるんですが・・・。
それだと、dllでbad_allocだしてくんなさそうだしな・・・。
>>335
new するほうってDLL使うほうだから特にboost側のソース書き直す必要ないってことすか?
dll使うほうだけでset_new_handlerしとくだけでいいんすかね?
C++の有名どころのクラスでマルチラインの
エディタの文字列を作ろうと思った時に、
std::deque<boost::shared_ptr<std::string> >
よりいい内部構造はないでしょうか?
>>337
stringをshared_ptrで包むのは却って無駄。
普通の実装では同等の機能で文字列本体を別保持してるってのと、
マルチラインの編集時は通常、複数の同一行コピーを持つのはレアケースかと。
外側はまあ適当に。メモリ効率を考えなければlistでいいと思うが・・
boostを書き換える必要なし。
mainの頭でハンドらをセットするだけ。
静的ななオブジェクト内でnewしてる場合は厄介かも。

つか、メモリアロケータを明示的にしている場合でも、
ソースまでいじる必要はないんだが..
>>338
>stringをshared_ptrで包むのは却って無駄。
>普通の実装では同等の機能で文字列本体を別保持してるってのと、
>マルチラインの編集時は通常、複数の同一行コピーを持つのはレアケースかと。

あ、なるほど。

>外側はまあ適当に。メモリ効率を考えなければlistでいいと思うが・・

中央部での挿入も多いので確かにlistの方がよい気もするのですが、
任意の行を表示する(例えば10000行目になった場合)時に
パフォーマンスが悪くなってしまうような気がして…

なんだか内容がスレ違いっぽくなってきてる気がするんで
どっか逝ってきます
>>340
リストで問題なのはn/2行目あたりへのジャンプが遅くなるだけ
行番号の表示は現在表示している位置を記憶して
そこからの差分で表示すれば問題ない

まあ、行リストじゃなくて行ベクタだとしても
秀丸程度のパフォーマンスにはなるはず。
あれは極端に行数が多いとパフォーマンスが落ちたけど
実用上ほぼ問題ないかな。
SGI STLのropeってどういう用途向けだっけか
>あれは極端に行数が多いとパフォーマンスが落ちたけど
秀丸の新バージョンは改善したとか書いてあったね。まだver4試してないけど……
>>342
逆にstd::stringでは何文字ぐらいまでが実用的か実験して
ご覧。予想外に短い文字数で使用不能になりません?
emacsのギャップ構造が一番エディタ向けで応答性も高い気がする
行ごとにメモリ確保するような構造はパフォーマンス的に問題あり
emacsってラインバッファがギャップ構造だったんじゃないの?
全体でギャップ構造を使っているのはxyzzyだったと思うけど
347329:04/01/24 14:18
>>339
ども、ありがとございました。
348デフォルトの名無しさん:04/01/25 02:10
C++ Templates(英語版)を入手して読んだ。内容は最初の方は
読む必要なし。PartUの"Templates in depth"当たりから読めば
面白い。C++ Primer(3rd)で説明してあった以上の事が書いて
ある。

早く和訳版出してくれ。と言っても英語版でも十分だが。
FC++って使ってる人いる?
351名無しさん@Vim%Chalice:04/01/29 13:22
CVS の先端の index.html には
> January 26, 2004 - Version 1.31.0
ってあるんだが、なんなんだろう、これは…
352デフォルトの名無しさん:04/01/31 04:43
Regex++のregex_grepで、クラスのメンバ関数をコールバック関数にすると
コンパイルエラーになるんですが、仕様ですか?
サンプルにあったregex(typedef reg_expression<char>)ならいけるんですが、
wregex(typedef reg_expression<wchar_t>)を使うとSTLのfunctionalでエラーになります。

環境:
Visual Studio.NET 2003
regex++でwchar_tというかunicodeを使ってはいけません。
シングルキャラクタ系の文字コードしか対応できないので
事実上ASCII専用の正規表現プロセッサです
正規表現をマルチバイト向けに翻訳して使うのが通
>>354
どういうこと?
UTF-8?
wchar_tもつかえると思うけど・・・。
UCS4/UTF-32なら使えるな
諦めてコールバックはstaticメンバにします。
359352:04/02/01 22:05
sage間違えました(´Д`;)すみません。
>>358
C++のプログラムで既存のCコードに依存するときに
よくあるやなパターンだな
もどかしい1.31.0
メタプログラミング系のライブラリはそろそろ完成したと
見ていいですか?
363デフォルトの名無しさん:04/02/04 19:35
>362
negative
>>362
まだ始まったばっかりだと思うけどね、言語仕様策定側もやっとboostの意味とかを理解し始めたばかりという感じだし、
そのレベルでのサポートが入ればまた激変すると思うよん
>>362
mplっていみじゃなくて?

1.31.0のmplってどうなってるかな?
1.30.0はまだ作りかけって感じだったけど。
templateのパワフルさ見てると
CとC++を足してC系の欠点(モジュール性とか
初期化順序の問題とか)を克服した言語に
templateを足した感じの言語が欲しくなるなあ。
値ベースと参照ベースをごっちゃにすることもなく、
GCもなくていい。C++と同様にlambdaとかFSMとか
コンテナはtemplateライブラリで提供する。

そんなC系最後の言語が欲しくなってきたなあ。
Dがその辺の立ち位置を狙ってるんじゃなかったか。GCもあるけど。
使用するポリシークラス(テンプレートのパラメータ)を
順不同で指定できるとかいうテクニックは、もうboostで使われてるの?
以前どっかで見たんだけど。
>>366
一応、今年中には .NET Framework に generics が導入される予定だけど。
>>367
Dでもやっぱり組み込みとかに使おうとう流れになるかは
微妙だ。オブジェクトが参照ベース+GCってのもちょっと…。
結局モダンなテンプレート利用法ってのは、プログラムを書くのではなく、プログラムを生成するプログラムを書くってところになると思うんだが
それで必要なものって何かって事について追求すると、現在のテンプレートが扱う言語要素が部品としてはいまいち使い勝手が悪いっていうか・・・
さらに今のCPUはC言語が必ずしも最適とはいえないし(Cは68000とかハードウエアスタックの実装が流行った時代の実装だと思う、インクリメント演算子とかは今は余計な気がする)、またCでは継続とかも実装できんし・・・
今の現代的なプロセッサに合わせて、まずベースになってる言語の見直しと、語彙・文法を作り出すメタプログラミングを可能にする要素の洗い出しをして
C,C++という言語はそれをベースにしたテンプレートライブラリとして実装とかになったら気持ちいいなとか思ったり。
んで、言語としては全面リニューアルとか
372366:04/02/04 23:46
>>371
同意ですな。
templateつうかジェネリックプログラミングのいい所は
いろんな抽象化概念サポートできるって所だと思う。
そう考えると言語はシンプルにして、例えば
boost::fsmみたいに抽象的な構造(状態遷移)は
templateライブラリを使って表現できるんじゃないかと。
多態とかだって関数ポインタとtemplate組合せりゃ結構
自然にサポートできるかも・・・。

とは言え、managedC++見たいな他言語とのインターフェース
部分だけはコンパイラがサポートする必要があるんだろうけど。
流石にCリンケージだけじゃつらいし。
継続なんてヘタに実装するというかよっぽど上手く実装しないと
資源(メモリ)の無駄使いの原因になるんだから
>>371の言う位置付けような基盤を担う言語には採用されるはず無いんじゃないの?
その手の言語に求められるのは高級アセンブラとしての側面だろうし。
374デフォルトの名無しさん:04/02/05 07:08
boost-1.31.0 age
375デフォルトの名無しさん:04/02/05 07:56
キタ━━━(゚∀゚)━━━!!
>>373
スタック⇔ヒープ間のデータ転送が必要になるから、逆にそこに必要な処理が入れられてないとダメだと思うよ。
それよりも、今のCPUってのはスタックらしいスタックがなくて全部汎用レジスタとして使われているから
そこを言語側から自由度をもちっと上げれば新しい世界ができると思うんだけどね。

あとメモリの無駄遣いといえば、この先起こる事として予想するのは、今はテンプレートは静的にしかコードを生成しないれけど
そのうち動的にプログラムがプログラムを書き始めると
今は、人間がシコシコ書いているからせいぜい数メガバイトにしかならないのが、一気に数ギガバイトとかとんでもない量に膨れ上がると予測するんだけど
そうなると、データだけではなく、コード側のガベージコレクタとか必要になるかなとか想像できて、
そこまで考えると継続という考え方を最初から導入するのも悪くないかなとか思ったり。
実際問題として静的にしか生成していない現在でもテンプレートを駆使したプログラムのサイズはヤバイものがあるし、なんか対策は必要かなとか思ったりする。
>>374
sourceforgeメンテ中・・・_ト. ̄|○
>>今はテンプレートは静的にしかコードを生成しないれけど
っていうかC++に限った話、必要だからコード実体化されたんであって、
コードを破棄する事ってできないんじゃないの?
実行メモリ節約の為に一度破棄して後で再実体化ってんならわかるけど。
逆にそれはやだなあ。
>>378
生成されるコードが有限なら大量にメモリー載せて使えるけど無限に生成されるように作ると嫌でも必要になるよん。
まあ、それはともかくテンプレートのとてつもない奥の深さを発揮するには、衝撃的な使い方に対する対策が十分に取られている事が結構重要と思ふ。

>>377
なぜにチンチン勃ってますか(^^;
しかも先っちょから出てるし・・・
Variantコンパイルするのに超時間かかるな・・・。
しかも有効な使いかたわからん。
おもしろいライブラリだとは思うんだが・・・。
もっとデザパタ勉強しろってことか・・・。

あと、enable_ifって、vc6だと使えんじゃないか・・・。
悲しいな。
sourceforgeメンテ中につきboost1.31がてにはいらん。
どこかにない?

382デフォルトの名無しさん:04/02/05 17:36
sourceforge キタ━━━(゚∀゚)━━━!!
>>377
メンテ終わったょ。
思う存分ハァハァ汁!
385デフォルトの名無しさん:04/02/05 19:10
STLport-4.6.1 age
最近VC6からVC7.1に乗り換えたのですが
あえてSTLportを使う利点とかってありますか?
>>386
バージョンアップする。
388デフォルトの名無しさん:04/02/06 11:24
VC6でSTLportとboostをスタティックリンクできますか?
BOOST_REGEX_STATIC_LINKを指定してもSTLportがDLLを使うようになってしまいます。
stdafx.h 内で
#define _STLP_USE_STATIC_LIB
を定義しる。

もしくは、
stl_user_config.h 内の

#define _STLP_USE_STATIC_LIB
を有効にしる。
390デフォルトの名無しさん:04/02/06 13:44
>>389

stdafx.hに
#define BOOST_REGEX_STATIC_LINK
#define _STLP_USE_STATIC_LIB
を追加したところリンクエラーがでてしまいました。

stlport_vc6.lib(stlport_vc646.dll) : error LNK2005: "public: __thiscall _STL::ios_base::_Loc_init::_Loc_init(void)" (??0_Loc_init@ios_base@_STL@@QAE@XZ) はすでに stlport_vc6_static.lib(locale_impl.obj) で定義されています
s

ちなみにboostをビルド時に
\boost\boost-1.30.2\libs\regex\build> nmake CXXFLAGS="-D_STLP_USE_STATIC_LIB" -fvc6-stlport.mak
とするとビルドできないようです。

こんなものが鮮肉に転がってたんだけど、

Apal C++ Library
ttp://www.essemage.com/aapl/

Aapl is a C++ template library for generic programming.
It contains Linked List, Avl Tree, Vector, Binary Search
Table, Double Ended Queue, String, and Sort.
>>391
STLの改良だけならもう既におなかいっぱいって感じだな。
>>390
BOOST_REGEX_NO_LIB
を定義した後で、
自分でregexのライブラリをスタティックリンクしてみる。

boost_regex_vc6-stlport_mss(d?).lib

とかいうライブラリだったような・・・。

てか、もう俺にはお手上げ。つかってたの大分前ナもんで・・・。
テンプレートをはじめて使ってみたがデバッグ歯肉すぎ!
>>394
デバッガなんて厨の使うもんだろ。
396デフォルトの名無しさん:04/02/06 18:40
template(とマクロ)だけ展開する方法ありませんか?
同じくデバッグ死肉すぎです。
stl(port) のやつなら どっかにあったな・・・。

てか、ライブラリなんて展開されたとこでデバッグできねーよ。俺には。
自分の作ったやつですら、ひぃひぃなのに・・・。

でも大体のエラーで何が原因かわかると思うんだけどな・・・。
templateはLISPで言うmacro-expandみたいなサービス欲しいね。
手探りするしかないってのはどういうことかと。
おなじくデバッグ刺肉すぎの業務連絡ですヨ
屍肉すぎ・・・
デバッガ使わないやつとかいるのか・・・
あんたが仕事でプログラムしてないことを祈るよ。
怪しいところがあったら普通は逆アセンブル画面見ながら調べるだろ。

by ゲーム屋
ゲーム屋みたいな使い捨て規模のコードなら逆アセで
追えんこともないかもな
規模が小さいとか大きいとかじゃなくて
デバッガだと、どういう手順で実行されるのかは判るが
テンプレートが、どういうコードを生成するのかは判らんから欲しいよ。
ていうか、この部分はテンプレートの肝だと思うけど。
デバッガ使うって・・・テンプレートでプログラムしている人間の発言とは思えんぞ〜
デバッグの方法論がない現状ではしょうがないね
昔Smalltalkが登場したばかりの頃もオブジェクト指向はデバッグが鬼門だって言われてたしね
それでも何とかなったし、もうちょっと研究されればマシなデバッガも登場するさ
>>403
MSがWinFXに向かってるところから考えて、
C++に対してはこれ以上は期待できないんじゃない?
それはC++に期待できないんじゃなくてMSに期待できないんじゃなかろうか
×C++に対しては
○MSのC++に関しては
×C++に対しては
○MSのC++に対する取り組みに関しては
boost::RegEx で wstring は扱えないのでしょうか?
ソースを覗いてみましたが、それらしい記述がありませんでした。
方法があれば教えて下さい。
>>408
無理。あと、RegExは1.31.0から非推奨クラスになったので使わない方がいいと思う。
>>401
> ゲーム屋みたいな使い捨て規模のコードなら逆アセで
昨今のコンシューマ機向けゲームは C/C++ で軽くコード 10 万行超えるぞ。
…………(  ゚,_ゝ゚)バカジャネーノ
>>409
えー、まじで。何でだろう。ライセンスがらみかな?
ちょっくら調べるか・・・。
413408:04/02/07 17:50
>>409
サンクス。自前でラッパークラス作るかなぁ…_| ̄|○
いやちゃんと読んでないけど、wchar_t も扱えるような template class basic_regex ができたから
RegEx が deprecated になったんじゃないのか?
wregex (basic_regex<wchar_t> の typedef) を使えば wstring を扱えるような感じだが?

ttp://www.boost.org/libs/regex/doc/index.html
regex_iterator良さげだなぁ。
regex++がVC7.1に正式対応したな。
良かった良かった。
>>414
いやそれはずっと昔からあるし…>basic_regex<wchar_t>

RegEx みたいなものを用意するより、basic_regex<> と iterator と
各種アルゴリズム関数で回すのがC++的スタイルだってことで、
要らんものを外したということではないかと。
RegExってお手軽っで結構好きなんですけどねぇ。
つか、ほとんど同じでwstring版を作ってしまったわけですが。_| ̄|○
419名無しさん@Vim%Chalice:04/02/10 14:52
g++ は変なコダワリ捨てて欲しい…
explicit specialization in non-namespace scope
とか言いやがって CLiPP がコンパイル出来ないじゃねーか…
STLでお勧めの本はなんでしょ?
>>419
この制限って自分はC++規格の不備だと思うんだけど、
いまだに規格に修正が入らないってことは、ちゃんとした
理由があるのかなぁ。どなたか詳しい人います?
>>420
Generic Programming
C++ Templates
Effective STL
Exceptional C++
>>422
thx
425デフォルトの名無しさん:04/02/12 00:29
boost本日本語訳出したら売れるのに
>>425
boost本ってグラフ以外に出てんの?
>>425
だんだん分厚くなっていくんか!!
てか、まだライブラリ事自体安定してるとはいえないから、難しいんじゃないの?
2.0が出れば ver1について書いてある本が出てくれれば買うかも。

>>426
グラフ本でてたのか!!
本読んで分ったような気になられても困る
429デフォルトの名無しさん:04/02/12 09:20
Boost C++ Libraries
http://boost.cppll.jp/HEAD/

が、googleで検索したらようやっと2番目になった記念age。
430420:04/02/12 23:40
>>423
アリガトン。
Effective STL以外は日本語版が無いような・・・
432デフォルトの名無しさん:04/02/13 00:56
#include <iostream>
#include <string>
using namespace std;

template<const string& S> class AAA
{
public:
     bool check()
     { return ("HELLO" == S); }
};

const string HELLO("HELLO");
const string WORLD("WORLD");

int main()
{
     AAA<HELLO> OK;
     AAA<WORLD> NG;

     cout << OK.check() << endl;
     cout << NG.check() << endl;

     return 0;
}

error C2970: 'AAA' : テンプレート パラメータ 'S' : 'HELLO' : 内部リンケージがあるオブジェクトを含む表現を、非型引数として使用することはできません。
error C2970: 'AAA' : テンプレート パラメータ 'S' : 'WORLD : 内部リンケージがあるオブジェクトを含む表現を、非型引数として使用することはできません。

ttp://tt.sakura.ne.jp/~suzu/template/template.htmlにオブジェクトへの参照もテンプレート引数に
渡せると書いてあったのですが、コンパイルエラーになってしまいます
オブジェクトへの参照はテンプレート引数にできないのでしょうか?
433432:04/02/13 02:58
const string HELLO("HELLO");
const string WORLD("WORLD");
のconstをはずしたらコンパイルできました

C2970を調べたところ

static 変数の名前またはアドレスは、テンプレートの引数に使用できません。
テンプレート クラスには、コンパイル時に評価できる定数値を渡す必要があります。

とありました
オブジェクト対してconstをつけるstatic constと解釈してしまうようです
>>433
C++ だと const 変数はデフォルトで内部リンケージを持つ。外部リンケージを
持たせたければ extern を指定しましょう。
ものすごく基本的な質問ですいません。
void function(char *cp) {
string s += cp;

/*cpには文字列が渡ってくる*/

これってできないのでしょうか?やってみましたができませんでした。
ポインタのさす文字列をstringに入れる方法ってないですか?
string s = cp;
>>435
入れるだけなら>436だし
追加したいならstrcatとか使わないと。整数と同じように足したって駄目。
>>437
おい。std::stringが何か理解してそう言ってるんだよ、な?
まぁ、>>435氏のために言うとくと、追加したいならstd::string::append()使えと。
string s(cp);
>>437
string s("hoge");
char* tmp = new char[s.size()+strlen(cp)+1];
strcpy(tmp, s.c_str());
strcat(tmp, cp);
s.assign(tmp, tmp+strlen(tmp));

???
>>435
int i += 5;
ができるか、どうか考えようや。
まぁ、operator あたりの勉強を再度してくることをお勧めする。
443435:04/02/14 10:02
>> 442
略しすぎで変なコードになってましたね…

>> 439
ありがとうございます。試してみます。
できないコードを持ってきて出来ないのでしょうかって質問の仕方はやめな。
自分でわかるところまでいろいろ試してみるべきだ。
別の擦れで見かけたコメント

「どうやったらできますか?」だと回答する気にもなるけど
「できますか?」だと「できる or できない」の一言で済ましたくなるし
「できないんですか?」だと「お前にはな」と書きたくなる。
ガイシュツの使い尽くされたネタだが、BCB5/6起動時にCtrl+Shift
を押しながら起動すると・・・・
>>446
どうなるんだよ。@VC++er
貞子が出るんだよ
449デフォルトの名無しさん:04/02/15 05:28
boostのmplで質問なんですが
以下のソースコードのBOOST_PP_REPEATの即値(4)を
消してsize<const_data>::type::valueをBOOST_PP_REPEATに
渡したいのですが、コンパイルエラーになってしまいます
プリプロセッサに即値以外渡せないのはなんとなくわかるのですが
そこをなんとか渡せるようにしていただきたいのです
よろしくおねがいします

using boost::mpl::list_c;
using boost::mpl::at_c;
uisng boost::mpl::size
#define MACRO(Z,N,LIST_NAME) std::cout << at_c<LIST_NAME,N>::type::value << std::endl;
typedef list_c<int,1,10,100,1000>const_data;
BOOST_PP_REPEAT( 4 , MACRO , const_data )
>>449
それは、とても、無理だ。
>>450
PPとmplの組み合わせに不可能などない!

>>449
PPで1からLIMIT_REPEATまでのバージョンを作っておいて、
mplで選ぶのはどうだ?
効率を気にするなら別の方法を考えないといけないが。
452デフォルトの名無しさん:04/02/15 22:39
pthread_t をmapのキーにしたいのですが、何かポータブルな方法はありますか?
Linuxあたりだとpthread_tがunsigned longだったりするので何も考えずにOK
なんですが..。

pthread_equal関数は比較関数の実装に使えませんよね。
453452:04/02/16 01:28
面倒くさいけどTLS使ってどうにかしてみます。
454449:04/02/16 06:15
template<bool Last=true> struct Printer{
   template<typename Itr,typename End> static void print(){}
};

template<> struct Printer<false>{
   template<typename Itr,typename End> static void print(){
      using namespace boost;
      std::cout << Itr::type::value << std::endl;
      typedef Itr::next Next;
      Printer<is_same<Next,End>::value>::print<Next,End>();
   }
};
int main()
{
   using namespace boost;
   typedef list_c<int,1,10,100,1000>   const_list;
   typedef begin<const_list>::type    Itr;
   typedef end<const_list>::type     End;
   typedef is_same<Itr,End>::type    Last;
   Printer<Last::value>::print<Itr,End>();
   return 0;
}
プリプロセッサはもっと勉強が必要っぽいので、今回はこれでいくことにしました
ありがとうございました
>>449
mpl::list_cにこだわらないならこういうのもある 文字列もいれられるぞ
#include <iostream>
#include <boost/preprocessor/array.hpp>
#include <boost/preprocessor/array/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

#define PRINT(z, n, text) print(BOOST_PP_ARRAY_ELEM(n, text));

#define CONST_DATA (4,(  1,           \
                  10,          \
                  "one hundred",  \
                  1000   ))

template<typename X> void print(X x)
{
   std::cout << x << std::endl;
}

int main()
{
   BOOST_PP_REPEAT(BOOST_PP_ARRAY_SIZE(CONST_DATA), PRINT, CONST_DATA)
   return 0;
}
初めて関数オブジェクトを自前で作って使ってみたんだけどかなり遅い・・・
使えねーと思いつつもReleaseビルドしたところ
今度は元のべた書きのソースと同じくらいの速さになった。
なんでこんなに変わるかなー
>>456
そらーinline展開とか不要変数の除去とかの最適化が入ったら、
関数オブジェクトのオーバーヘッドはほとんど消え去るからねえ。
>>457
確かに最適化を期待してReleaseにしてみたんだけど、
元ソースと遜色ない程度までとは思わなかった。
こうなってくるとかなり使えそう。
>>458
EffectiveC++買いなさい。損はしない。
>>459
EffectiveSTLじゃないの?
>>460
あ、間違えた。dクス

>>458
EffectiveSTL買いなさい。損はしない。
間違えたこの際だから、
EffectiveC++もMore EffectiveC++もEffectiveSTLも
ぜ〜んぶ買いなさい。オホホホホホホ
あとはModernC++Desingかな
Exceptional C++も買っとけ。
Efficient C++ もな.
ピアソンエデュケーション大儲けだな(w
More Exceptional C++もオシシメ。
もうすぐExceptional C++ Styleってのも出るらしいよ。
EffectiveC++もMore EffectiveC++もEffectiveSTLも持ってる。
EffectiveC++は読んだ。More EffectiveC++は読み途中(7ヶ月経過)。EffectiveSTLは買っただけ。
とりあえずMoreは中断してSTL読むよ。

ModernC++Desing、Efficient C++はタイトルだけ知ってる。
お勧めなら読んでみようかな。

ModernC++Desing はお勧めってゆーか、必須だよ
これを読んでおかないと最近のtemplateライブラリーのソースは見ても、謎の暗号でしかないからね。
たしかに必須だけどさ。あれ全部理解するの大変だよな。3ヶ月くらい前に買ったんだけどまだ3割くらいしか理解してないよ俺。
C++ Templates (英語版)も読もう。もうすぐ和訳版が出るヨカ〜ン
だけど。Part1は全く読む必要ないからPart2以降を読むと良い。
ある程度読んだらもうどうでもいい領域にいくよな。
Modern C++ Designは確かにポリシーのパラメータ化という
有用な方法を身につけるには良いと思うが、テンプレートライブラリを
理解したり開発したりするときのテクニックの面では必須というほどでもないと思う。もちろん、役に立つとは思うが。
俺としては、プログラミング言語C++を推薦したいな。
常識だといわれるかも知れんが、しっかり読んでいればたとえば
Modern C++ Designの冒頭のPhisicalテンプレートくらいは当然の発想として思いつけると思う。
実装テクニックが知りたければ、boostのコードを読むのが手っ取り早いんじゃないか。
まぁ、Preprocessorを覚える必要はあるが。
More Exceptional C++ って本屋で見かけないなぁ?
販売数が少ないんかな?

Exceptional C++ なら見かけるんだが…
>>474
洋書
>>474
未訳なので洋書コーナーにあるかもしれんね。
漏れはamazonで買ったけど。
>>474
ああおれもamazonで買ったけどな。英語でもプログラミング関係
の本は決まった単語しか出てこないから意外に読めるよ。
海外長くすんでた漏れから言わせてもらうと
プログラム系の英文は文法自体は小学生でも分かる。
専門用語多いから小学生にはよめんけどね。
そんな事いうなよ
洋書なんかまじめに読もうとすると1ページ10分以上かかるのが
情けなくなってくるじゃないか
480474:04/02/19 04:16
>>475-477
3人連続でレスがくるとわ…
dです。

洋書だったんか。
どーりで見つからんわけだ。
>>479
日本語で書いてあってもそれくらい時間かからんか?ページによっては。
まぁ訳が良ければすいすいだけど。
中学のときの英語を真面目にやっておいて良かったと思う。
当時は学校英語なんて…と思っていたけど
MSDNとか読むときとても役立ってる。
中卒でもなければ高校でも大学でも英語はやるだろ
一瞬推薦図書スレかと思った。
STLをふんだんに使ったマスターマインドのゲームか・・・・
初めて見たよこの手のプログラム。
486478:04/02/20 00:09
どうしてもわかんない英文とか、分かるけど時間かかりすぎ。ってのがあったら
このスレの住人がかまわないならここで聞いておくれ。
そういう仕事もあるから俺も勉強になる。
ベタの全文翻訳を頼んでくる客も多いけど、こっちとしては
そうでなくて、読み解くコツみたいのを技術者に伝授するほうが
ずっと理解も良いし早いと思うし、金も儲かりそうと考えているからね。(笑

まずは、家の社員でも多いけど、
「僕は英語苦手だから、読めないから」って言葉を口に出すのをやめることからはじめてみよう。
この当たりもいいのではないかとさりげなく書いてみる。
ttp://homepage1.nifty.com/Mercury/ohoyamak/
489デフォルトの名無しさん:04/02/21 20:16
linuxにboostインストールする方法教えて下さい
emerge boost
bjam install
492デフォルトの名無しさん:04/02/22 00:39
>>491
それやって、サンプルコードコンパイルしようとしたら、
インクルードファイルが存在しないっていうエラーがでるんですが、
なぜなんでしょうか?
>>492
そのインクルードパスに実際にファイルが存在してるか確かめれ
494543:04/02/22 00:42
>>492
cd /usr/local
ln -s boost-1_31 boost
とかなんとか。覚えてないけど。
× cd /usr/local
○ cd /usr/local/include
Windows xp Home Edition & Metrowerks CodeWarrior Pro 8.2で
boostをビルドしてインストールしようとしたら次のように表示されビルド
されませんでした。どうすればよいのか分からないので教えてください。
お願いしますm(_ _)m

C:\Documents and Settings\user\My Documents\boost>bjam -sTOOLS=cwpro8 install
allyourbase.jam: No such file or directory
boost-base.jam: No such file or directory
C:\Documents and Settings\user\My Documents\boost\tools\build\v1\bootstrap.jam:15: in boost-build
rule load-jamfiles unknown in module
C:\Documents and Settings\user\My Documents\boost\boost-build.jam:16: in module scope
>>496
C:\Documents and Settings\user\My Documents\boost\tools\build\v1\
にallyourbase.jamとかboost-base.jamはちゃんと存在する?しなければ
ダウンロードミスか何か。あと、bjamは最新版を使ってるか?

ついでに関係ないんだけど、CodeWariorって使いやすい?
買ってみようかどうか迷ってるとこなんだが。。。
498496:04/02/22 01:05
スペースの入ってないパスに移して実行したら行けました。スレ汚しスマソ。
499デフォルトの名無しさん:04/02/22 01:12
>>494
それやっても、また今度は別のエラーが、、、
きりないなぁ
500496:04/02/22 01:20
>>497
慣れればいいと思うんですけど、GUIの癖はすごく強いですねぇ…あと、ヘルプがクソです。設定等は比較的しやすいかと。
リソースファイルはスクリプトを自分で書かないといけません。あと、日本語版はまだですが、バージョン9が出ますよ。
VCとモジュールのバイナリ互換がとれてない部分(メンバ関数のポインタレイアウトとか)は多々あるので、ライブラリ単位での共有は難しいかと。
>>499
とりあえずエラーさらせ。
>きりないなぁ
>>494 程度が自力で対処できないなら仕方ない。
vc71にboostとSTLportの最新のやつ入れてみたけど
regexのstaticライブラリがうまくリンクできない。(releaseはok)

前のverでもかなり試行錯誤したけどなんでさあ。
>>502
boost::regexとSTLport、どっちか一方ならうまくいくんですか?
VCのSTLは使いたくないんで、できたら両方使いたい。

STLportだけならokですが、
spirit+regexのコードを前のバージョンからつかってるので、regexは必須。

リンクが通らないのは regex系のクラスです。
regexだけは試してないや。夜にでもやってみまつ。

>>502は、release版ではできるけど、debug版ビルドで
static linkができないってことです。

VC6とVC7.1のVC標準STLって、どこが変わったかわかるひといます?
505497:04/02/22 14:12
>>500
なるほど...。アリガトン。
dinkum>stlport
>>504
ヘルプの
Visual Studio.NET>Visual C++>移植とアップグレード
あたりから辿れる情報以外でか?
STLPortを使わずにregexだけなら行けます。
STLPortありでは漏れも昨日の夜格闘したけど結局うまくいかなかった。
>>508
エラーメッセージでも貼り付けてはいかがか?
ばんどう たまぶらさげたろう
511502:04/02/23 01:39
今日無理。明日続きを報告
512502:04/02/23 15:12
落ち着いて見直した。
boost::regexのライブラリビルド時にSTLport-4.5.3を参照していたのがいけないっぽい。

STLPORT_PATHを4.6.1側を見るように直してbuild

(´д`;;)トオッタ
質問です。
boostをインストールすると、デフォルトではヘッダが別フォルダに
コピーされるようです。これにはどのような意義があるのですか?
教えてください。お願いします。m(__)m
せめてお前の環境とどうやってインストールしたかぐらい書かんと答えようがない。
インクルードパスが通ってるところにあればどこにあっても構わんはずだが。
515デフォルトの名無しさん:04/02/23 20:21
vectorクラスのアクセス方法で添字演算子[]とat()関数ってどう使い分けたらいいのでしょう?
範囲外の要素にアクセスアクセスしたとき
at() 例外を備えている
[]  定義されていない
at()のほうがよさげだけど[]もあるってことは何か理由があるのでしょうか?
>>515
vectorは連続したメモリを確保するから、配列みたいに扱えると便利ってことじゃないの?
>>515
範囲チェックが無い分、[ ] の方が速い(場合がほとんど)。
ので、事前条件チェックで範囲外アクセスが起きる可能性を
排除してから [ ] を使う、ってのが一番現実的ではある。
STLのmapについて質問があります。mapの反復子を参照するとキーと値のpairを
返しますが、このとき次のようにすると、
map<int, int>::iterator i;
...
i->second=1;
mapの内部の値を書き換えることが出来ますよね。このようなことをするためには
どのようなテクニックを使えばいいのか教えてください。

次のようにしたときには、値を書き換えることができない。
int a=1, b=2;
assert(a==1);
pair<int, int> p(a, b);
p.first=3;
assert(a==1);

かと言って、次のようにするとコンパイルすることが出来ない。
int a=1, b=2;
assert(a==1);
pair<int&, int&> p(a, b); // 参照の参照になっている

どういった仕組みになっているのでしょうか?
>>518
いや、テクニックも何も、map<int,int> は内部に pair<const int, int> を
保持しているので、*iterator が pair<const int, int>& を返すだけ。大抵の実装では。

あなたの書き方で書くと、
pair<int,int> x( 1, 2 );
pair<int,int>& p = x;
p.first = 3;
assert( x.first == 3 );

--
mapの実装に限らず>>518の後半のようなコードを書きたいなら、
boost::tuple を使うか、 pair<> の中身に boost::ref を使うのが簡単かと。
>>518
つうか、質問の意図がどこにあるのか読み取りにくにような。
「既に存在しているオブジェクトにインデックス付けし、
インデックスをキーにしてそのオブジェクトを読み書きしたい」
という目的にmapを使いたいなら、素直にmap<int,int *>使えば
良いと思う。(*の代わりにboost::refでも良いけど・・・)
pair<>についての質問なら519の通りだけど。

話変わるけど、参照の参照って次のC++で直るん?
521デフォルトの名無しさん:04/02/24 10:43
std::map< A*, B* > hoge;
std::map< B*, A* > mage;

というような感じで、両方ともキーになれるマップで、代入、削除はどちらか指定するだけ
っていうのは、variantでスマートに書けたりできます?
前だれかが作ってましたよね。
早くboostにはいってくれないかな?
522518:04/02/24 12:21
>>519-520
すんません。STL風のコンテナを作りたいと思っていて、値とその値に関連した
データを保持するものです。ですが、2つのデータをpair<>にそのままいれる
ことが出来なかったので、別の形で値を保持していました。このときに、mapの
iteratorへの参照みたいなことをしたいと思っていました。そのときに質問の
ようなことを疑問に思ったわけです。

回答どうもありがとうございました。
template <class InputIterator,
              class BinaryPredicate>
inline
InputIterator
adjacent_mismatch(InputIterator first,
                          InputIterator last,
                          BinaryPredicate pred)
{
  if(first != last)
  {
    InputIterator i = first;
    for (++i; i != last; ++i)
    {
      if (!pred(*first, *i)) return i;
      first = i;
    }
  }
  return last;
}
と同じこと(↑のは自作です)をSTL(boost可)でしようと思ったら
どうすればいいですか?隣同士が等しい範囲の「次」の
iteratorを返したいんですが。adjacent_findもmismatchも
first==lastのときfirst+1が必要になるし…
>>522
もう続ける気がないなら意味ない詮索だけど、何度読んでも
何が疑問で何を訊きたいのかわかんない・・・。
>>523
adjacent_find(first,last,not_equal_to())か
adjacent_find(first,last,not2(pred))とかじゃだめ?

>first==lastのときfirst+1が必要になるし…
VC6の実装はそうでもなさそうだけど。
>>523
そのコード InputIterator ではなくて ForwardIterator が必要だと思うんだけど…
http://www.sgi.com/tech/stl/InputIterator.html
> [3] After executing ++i, it is not required that copies of the old value of i be dereferenceable or that they be in the domain of operator==.

ForwardIterator でよいなら、普通に
 i = adjacent_find( first, last, boost::not2(pred) );
 return i==last ? i : ++i;
で行ける。InputIteratorを取りたいなら自前でループ書くしかないだろうねぇ。
527523:04/02/24 21:52
>>525,526
レスありがとうございます。すいません、入力演算子かどうか
自信ないです。勉強しなおします。なるほど、3項演算子と言う
手がありましたか!
528526:04/02/24 23:19
いや3項演算子は全然本質に関係ないっす。普通にif文で書いても同じこと。
529523:04/02/25 02:22
>>528
for文の普通インクリメント書くとこに書きたかったのです。
どうもありがとうございました。車輪の再発明せずに済みました。
自分の書いたコードはあまり信用できないですから。
530518:04/02/25 04:39
>>524
説明べたですみません。

template<class Key, class Value>
class my_map
{
 vector<Key> vector_keys;
 vector<Value> vector_value;

 class iterator
 {
  ? operator*(){ // キーと値のpairを返したいがどうやったらいいのか?
  }
 };
};

こんなようなクラスを書き、?のところを
my_map::iterator i;
Value value;
(*i).second=value;
こういう式が受け入れられるような型ってなんだろうと思ったんです。
>>530

template<typename T>
class reference
{
 T& ref;
public:
 reference(T& r) : ref(r) {}
 operator T&() { return ref; }
 operator const T&() const { return ref; }
 const T& operator=(const T& n) { return ref = n; }
};

こんな感じのをつくって、std::pair<int, reference<int> > とするのはどうかな
>>531
既出(boost::ref)
533デフォルトの名無しさん:04/02/27 17:32
>>353って具体的になにが駄目なんですか?
wregex r( L"[あ-お]" );
とかがマトモに動かない、とか。
っていうかそれが動く正規表現プロセッサ実装が
あるんだ。はじめて知った。でも
wregex r( L"[あいうえお]" );
なら動くからまあいいんじゃない?
あ-ん は連続していると考えていいの?
a-z の範囲で連続してない文字コードもあるわけだけど
連続していなくても使えなければ、正規表現ライブラリとしては実用に耐えない。
ShiftJISのダメ文字とかも苦手だし、boost の文字列処理系のライブラリは避けたほうが無難。
>>534
マトモに動かないってどういう風に?
とりあえず"いろはにほへと"に対して"[あ-ん]*"はマッチしたし"[あ-お]*"はマッチしなかったが。
>>537
shiftjisの駄目文字とunicodeは関係ないだろう?
シフトJISやらUnicodeやらのひらがなの並びを考えれば、
[あ-お] は [あぃいぅうぇえぉお] になるわけだが、それでいいのか?
それとも、いちいち [あいうえお] になるように実装しろと?
541534:04/02/28 09:23
>>538, >>540
いや、俺は(例えばwchar_tがUCS-2なら) [あ-お] が
U+3042 〜 U+304A [あぃいぅうぇえぉお] にマッチしてくれれば
十分なんだけど、マッチする?
542534:04/02/28 09:29
あー、マッチしてる。漏れのwstreamの使い方が変で結果の
表示がされてなかっただけだた。。。忘れてけれ。
結局無いんだな
544デフォルトの名無しさん:04/02/28 17:45
いまvectorの要素をチェックしてだめなものを間引くとします。
std::vector<foo *>::iterator it;
for(it = m_list.begin() ; it != m_list.end() ; ++it)
{
   if(*it->isOk() == false)
   {
      delete *it;
      m_list.erase(it);
   }
}
などとやったとします。このようにループ中にeraseで要素を破棄して配列を切り詰めたとき
このループは正しく次の要素をチェックできますか?
>>544
イテレータの次の地点はeraseの戻り値で置き替えないと駄目。
if ( ... ) { it = m_list.erase(it); } else { ++it; } みたいに。

あとメモリ解放のポリシーも手動は悲しいな。といってもstd標準だと自動化できない
(auto_ptrはコンテナに入らない)からboostのscoped_ptr/shared_ptrとかが欲しくなるが。
>>544
正しくありません。eraseは反復子を無効にします。
解決策として、反復子でなく添え字で管理する、std::remove_ifを使う、などが
あげられます。
547546:04/02/28 17:54
失礼、remove_ifは使えませんですね。
>>546
VC++ だと、こんなコードで動いてるんだけど
実装依存なのか?

it = m_list.begin()
while (it != m_list.end())
{
   if(*it->isOk() == false)
      m_list.erase(it);
   else
      ++it;
}
なぜその用途にvectorを使うのか理解できない


>>549
>>544>>548 の内容だけじゃ何が最適かは判断出来ないと思うが・・・
551544:04/02/28 19:14
みなさん。ありがとうございます。
やっぱり間違いでしたか。
とりあえず、>>548さんのように書き換えました。

ついでにお聞きしますが、今回std::vector<foo *>ですが、
なぜ自分はこんなやり方をしてるかというと、単にeraseした時に
fooのデストラクタが呼ばれるのか不安だったためです。
つまり
foo f;
m_list.push_back(f);
m_list.erase(it);
ではfの実態はデストラクトされないのではないかと勝手に思い込んでいるからです。
(検証すればいいだけのことだけど)

ではでは。
>>551
呼ばれる。安心しる
>>551 >>552
fのデストラクタは呼ばれないが、vectorが内部に持っているfのコピーのデストラクタは
きちんと呼ばれる。それに、fのデストラクタをvectorが勝手に呼んだら、fがスコープを
抜けるときに困るだろ。
安心しました。今後はstd::vector<foo>でいくようにします。
本当にお世話になりました。m(_ _)m
555552:04/02/28 19:47
>>553
"eraseしたときにfooのデストラクタが呼ばれるか"って観点だったが
push_backではコピーコンストラクトされたものが格納される点には注意だね。

あと >>548
vectorに限ってはitを更新しなくとも、大抵の実装では"たまたま"次の要素を
指すだろうが、規格ではeraseはすべてのiteratorを無効化するので駄目だし
あとでlistなんかに書き換えた途端に困ることになるよ。
it = m_list.erase(it);
とやっておくと幸せになれま。
557デフォルトの名無しさん:04/02/28 19:58
>>555
vectorの場合、
削除した後のすべての反復子と参照が無効になると思ってたんだが、
違うの?
558555ではないが:04/02/28 20:04
>>557
だから「規格では」その通り全てのiteratorが無効化する。
「たいていの実装では」"たまたま"次の要素を指している。
>>557
>削除した後のすべての反復子
てのは、削除した要素よりも「後ろ」の反復子、って意味なんじゃないか?
>>559
ということは、削除した要素を指していた反復子は無効化しないのが正しいのか?
でもいつのまにか次の要素(またはend)を差すことになるのは仕様として変な気が・・
>>560
だから規格では(or仕様としては)無効化するので正しいんだってば。
おまいは人の話を聴け。

ただ、多くの実装はこんな感じ
 template<typename T> class vector {
  typedef T* iterator;
  iterator erase( iterator it ) {
   for( iterator i=it, j=it+1; j!=m_end; ++i, ++j ) *i = *j;
   call_destructor( --m_end );
   return it;
  }
 };
をしてるせいで "たまたま" 次の要素を指してるかもしれんけど、
それを期待してコードを書くのは大間違いだ、って話。
>>557は「全て」ってなんだよっていうのを確認したいんじゃないの?
普通に「全て」といったらbegin()からend()までをいうように俺は思うんだけど、
> -3- Effects: Invalidates all the iterators and references after the point of the erase.
ってかいてあるよ?
>>561
どうでもいいが call_destructor( m_end-- ) じゃね?

>>559
そうだね。「Invalidates all the iterators and references after the point of the erase」だ。
564548:04/02/28 22:37
iteratorが無効になるとしたらどっちのコードが正しいの?

it = m_list.begin()
while (it != m_list.end())
{
   if(*it->isOk() == false)
      it = m_list.erase(it);
   else
      ++it;
}

it = m_list.begin()
while (it != m_list.end())
{
   if(*it->isOk() == false) {
      m_list.erase(it);
      it = m_list.begin();
   }
   else
      ++it;
}

上。
Effective STLの9項読め。
567デフォルトの名無しさん:04/02/29 00:01
age
iteratorが無効になるのが正規の仕様だとしたら
このiteratorは何処を指すことになるのだ?

it = m_list.erase(it);
>>568
削除された要素の次の要素。
じゃ、
it = m_list.erase(it) と m_list.erase(it) は殆どの処理系で同じ動きになるのか。
>>570
後者は未定義だって。
>>571
後者の動作が未定義なのではなく、そのitが無効になることが定義されている。
ていうか、
仕様できちんと作用しないことが定義されていて、
その解決手段が提供されているにも関わらず、
>>570みたいなことを言う奴の考えが理解できないんだが。

プ ロ グ ラ ム な ん て 動 け ば 良 い や ん。

>>574
そのスタンスで作られたプログラムは通常客の前に限って突然動かなくなる。
と、釣られてみる。
>>574
そういう香具師に限って一切の妥協の無いコーディングをする罠。
>>576
ハゲ同、
動けばいいなんて許せないという奴に限って、忙しいとか言い訳つけてメチャクチャ
OO最高っていっている奴に限ってOOになってない
設計設計いっている奴に限って設計メチャクチャ
なぜか、逆も真ナリ
「〜に限って」と言う奴は視野が狭い。

限ってねーよ。
マ板っぽくなってきたな(w
580571:04/02/29 16:06
>>572
舌足らずだったか。正確には、後者の文を実行後に it を操作したときの
動作は未定義、だね。

イテレータが無効になるから参照はがしや ++, -- なんかを呼ぶとどうなるか
分からん。たとえば STLport のデバッグモードを使っている場合は、即座に
assert() で叩き落とされる。
vector から要素を一括削除する場合、ふつー自前でループを回さずに
<algorithm> の remove_if() と vector<T>::erase() を組み合わせて使う。
要素を一つ削除するたびにコンテナの残り要素を移動し、さらにコンテナの
先頭から検索し直すのは非効率だから。

また vector に new したポインタを直接突っ込むと、要素を
削除するときに明示的に delete が必要になるなど、何かと面倒が多い。
スマートポインタを使うのがお薦め。
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/construct.hpp>
#include <boost/shared_ptr.hpp>

class foo
{
public:
  foo(bool ok) : m_ok(ok), m_count(ms_count++) {}
  bool isOk() const { return m_ok; }
  int getCount() const { return m_count; }
private:
  static int ms_count;
  int m_count;
  bool m_ok;

  friend std::ostream& operator<<(std::ostream& os, foo const& x) {
    return os << x.getCount() << "[" << x.isOk() << "] ";
  }
};

int foo::ms_count = 0;
int
main()
{
  using namespace boost::lambda;
  #define NELEM(x)    (sizeof(x) / sizeof(x[1]))

  static bool data[] = { 1, 0, 1, 1, 0, 0, 1 };

  std::cout << "init: ";
  std::vector<boost::shared_ptr<foo> > v;
  std::transform(&data[0], &data[NELEM(data)], std::back_inserter(v),
      bind(constructor<boost::shared_ptr<foo> >(), (bind(new_ptr<foo>(), _1)))
      );
  std::for_each(boost::make_indirect_iterator(v.begin()), boost::make_indirect_iterator(v.end()), std::cout << _1);
  std::cout << std::endl;

  // isOk() が false を返すヤツを削除する
  std::cout << "del: ";
  v.erase(std::remove_if(
        boost::make_indirect_iterator(v.begin()),
        boost::make_indirect_iterator(v.end()),
        !bind(&foo::isOk, _1)).base(),
      v.end());
  std::for_each(boost::make_indirect_iterator(v.begin()), boost::make_indirect_iterator(v.end()), std::cout << _1);
  std::cout << std::endl;
}
>>582-583
スマートすぎて声も出ないな。

ところで、lamda式の側で参照はずししないでわざわざboost::indirect_iteratorを使うのはなぜだ?
lamdaって何だよ…
orz
586582:04/02/29 18:09
>>584
手元の gcc 3.2.3 だと vector<foo*> に対しては *_1 と書けるんだが、
vector<shared_ptr<foo> > だと *_1 がコンパイルエラーになるから。

何か良い方法ある?
>>586
なるほど、納得。

>何か良い方法ある?
ret<foo>(*_1)位しか思いつかねえや。スマソ。
> ret<foo>(*_1)位しか思いつかねえや。
その手があったか。汎用性は失われるが、make_indirect_iterator より
記述が短くなって良い感じ。
こんな手もありますね。

namespace boost {
namespace lambda {

template<class T>
struct plain_return_type_1<other_action<contents_of_action>, shared_ptr<T> > {
typedef T type;
};

}}

boostしか関わっていない特殊化をユーザーがするのは気がひけますが…
s/contents_of_action/contentsof_action/
>>586
それ確かCVSには修正入ってるはず。boost-devで見た記憶がある。
C++ を better C、vector を better 配列としてしか使えない漏れは逝ってよしですか?
>>591
最新版で *_1 でコンパイルとおった。

> revision 1.6
> date: 2004/02/24 13:13:03; author: pdimov; state: Exp; lines: +3 -1
> *_1 support for smart pointers

使うには、次のリリースを待たねばならないらしい。
>>589
typedef T& type にしないと、コピーが発生する模様。
595デフォルトの名無しさん:04/03/01 16:16
異なる型の間で、値をクランプするようなテンプレートって作れませんか?
例えば、WORD型で表されている数値をBYTE型で表現できる範囲にして
割り当てるような。
意味分からん?
>>595
template <typename Dst, typename Src>
Dst clump(Src s)
{
typedef std::numeric_limits<Dst> destlim;
if(s > Src(dstlim::max())) return dstlim::max();
if(s < Src(dstlim::min())) return dstlim::min();
return Dst(s);
}

こんな感じ?
597595:04/03/01 17:50
「クランプ」の使い方が間違っていました(笑)
私が言おうとしていたことは、
http://www.ruche-home.net/program/bmp/bitfields.phpにある
「ビットフィールドからRGBへ」の内容と同等です。
8ビットのBYTE型やWORD型で表された値を、7bitなどで表したいのです。
今までCとJavaをやってきたんですが、C++とSTLを
使うことになりました。んが、デバッグがやりにくかったり
OO的なところとジェネリックプログラミング的なところが
混じったりするのでいまいち好きになれません。

みなさんはSTLに開眼するきっかけとかありましたか?
便利なのはわかるんですが、僕はまだ吹っ切れません。
>>598
JavaのコレクションとSTLを比べても、Javaのほうが良いと思うわけ?
それが信じられない。
"C++とSTL"って、まるで別物のような書き方だな。
>>595,597
意味わからん。
確かにC++にはOO的な部分とgeneric programmingとが混在していて美しくは感じないかも
知れないが、それだけ懐が広いとも言える。言語は手段であって目的ではないのだから、
用途によって使い分ければいいのであって、様々な言語の長所と短所とを如何に熟知し、
使いこなすかが職業プログラマの腕の見せどころであると思うのだが如何か。どの言語が
絶対的に優れているか等と言う議論は、そのものが不毛である。仕事上扱うことになった
のならば、自らの技術向上に役立てる機会が与えられたのだと考え、喜んで受ければよい。
C++はtemplate周りに落とし穴が多い。汝、精進すべし。
>>599
そんなことは言ってませんが。なんでJavaの名を聞くだけで
突っかかってくるんですか?

>>600
昔のSTLが標準でない時にC++を少しやって
なんとなくそれが自分の中で基準になってたんで。
すまそ。

>>602
好きにはなれないけど、がんばります・・・。
>>603
なんで質問するだけで「突っかかってくる」とか妄想しちゃうんですか?
>>603
つうかC++スレでああいう書き方してたら誰だって599
の様にかきたくなる。C++のまえに人間関係
勉強しなおしたら?
606602:04/03/02 01:09
>>604,605
まあまあ、お二方共、熱くなられるな。私は、>>603 は如何にすればC++の素晴らしさを
知ることができるのかと言う教えを請いたいと述べているのだと、受け取った。自分も
その素晴らしさに開眼したいのだ、と。非常に謙虚な良い態度だと思う。いい機会
なのだから、むしろC++の素晴らしさを教えてあげればよいのではないかな?
まるちぱらだいむまんせー
誰が読んでも599は悪意のある皮肉だろ
しゃあしゃあと煽る604ワロタw
こういう二人は別にJavaとC++というスタンス無しでもきっと
喧嘩する。ほっとくが吉。
template<typename T>
class A
{
typedef T::X X;
}

class B : public A<B>
{
class X{};
};

↑のコードはA<B>::XでB::Xに言及する意図があるのですが,
Bのインスタンスを作ろうとすると,Bの定義を見る前に
A<B>をインスタンス化しようとするので怒られます.
なんとかならないでしょうか?
すいません.↑のclass Aとclass Bのメンバは全てpublicです.
>>610
typedef typename T::X X; じゃ駄目?
あ,すいません.typename抜けてました.
何度も申し訳ないです.
>>598
JDK1.5でJavaもテンプレートをサポートしているわけだが。
JDK1.4までのJavaはどうにもCollectionのあたりで
ダウンキャストが避けれないつくりになっててスマートじゃない。
STLはそのあたりスマートに解決できる。
615デフォルトの名無しさん:04/03/02 21:41
>>610
class B;
って先に書いたらだめ?
前方宣言もダメなんです.
B::Xに言及するためにはBが定義されている必要があるわけで・・・
>>614
あんな10年前のC++並の使い方しか出来ないようなもんでtemplateサポートしたとか言われても。
>>616
それって、前方宣言で
class B; // <= OK
class B::X; // <=NG
ってなっちゃうのと同じ問題じゃないの?
619610:04/03/03 02:01
やっぱりXを外で定義するか,
ネストするにしてもA, Bと同じ継承関係を書いた方が良さげですね・・・
#include <stdio.h>

typedef class _B B;// これは出来る
typedef class _A<int> A;// これは出来ない ???

class _B
{
public:
_B( ) { printf( "B desu\n" ); }
};

template <typename Type> class _A
{
public:
_A( ) { printf( "%d\n", sizeof( Type ) ); }
};

//typedef class _A<int> A; // これは出来る

void main( )
{
A a;
}
-
???の行でエラー出るんですが、
これが出来ない理由を知りたいんですが、
分かる方いらっしゃらないでしょうか?
>>620
template <typename Type> class _A;

前方宣言しる。
A.Alex の人が 一時コピーをなくすために mojo とか言っていたけど、
あれって、pimpl イディオムを使っているようなものにしか使えないし、
オブジェクトへのコピーを返すような関数でも、最適化によって mojo を使うほうが
遅くなるってことは無いのかね。
>>621
出来ました。
理由もなんとなく分かりました。
どうもでした。
template使えば整数の演算のうちのほとんどをコンパイル時に値が決定できる
形で書けると思うんですが,そういうのを網羅したライブラリってありますか?
ないなら自分で簡単に書いてみようと思っているのですが・・・
整数演算って例えばどんなの?
>>624
Boost
>>624
metaprogrammingライブラリ(boost::mplとか)のサブセットとしてなら
いくらかあるかもしれないが”網羅”ってどの程度だろうね……。
そういうのはコンパイル時 if みたいなメカニズムを用いた
コード生成がメインで定数の生成を主目的としたものじゃないし。

実際問題それ単独では大して役に立たないと思うなあ。
ある程度複雑な演算機構を必要とする上で
全てのオペランドがコンパイル時定数で
しかも整数演算以外の機構を必要としない
なんてケースは考えにくいから。

勉強にはいいと思うけど。
template<int I> struct fibonacci{
static const int value
= fibonacci<I-1>::value + fibonacci<I-2>::value;};
template<> struct fibonacci<0> {static const int value = 1;};
template<> struct fibonacci<1> {static const int value = 1;};

こういうのをもう少し高い視点から一般化できないものかな。
数学ニガテな漏れにはわからん。
そこまで求めるなら関数型言語使えというのは禁句か?
つーかそれはメカニズムの問題じゃなくて記法が問題な気がする。
単なるパターンマッチングの部分を
丸ごとクラステンプレートの部分特殊化で記述するのがあまりに冗長というか。
とにかく機構自体はすでに十分一般化されてると思う。
630624:04/03/08 21:43
>625
私がイメージしてたのは628さんのような例ですね.

>627
確かにふと思いついただけの,勉強と趣味の域を出ないものでして,
おっしゃるように用途は?と訊かれたら返答に困りますね.
むしろどんな使い方が考えられるか?を訊いた方が良いですね.

>628
複雑な数値の静的な解決を行うには結局はこういう再帰的な書き方しかできないと思います.

>629
確かに現在の書き方はスマートではないですね.
個人的にはinlineの再帰的な関数templateの形で書けたほうがうれしいとは思います.
メタプログラミングも関数型言語も通り越し、
数論の世界へ。して廃人。合掌。
FC++は?
なんでboost/lambdaはpreprocessorを使わないんだろう。
お陰でVCのエディタが頻繁にフリーズする。
BOOST_PP_ はなるべく使わないようにするというのは
最低限のマナーだと思うけど。
もうあれだ、
これからはC++コンパイラは標準でインタープリタを内蔵することにして、
Lispみたいなマクロを使えるようにすりゃ素晴らしい世界になるよ。
perl 内蔵とかでもいいかも。
GNUのm4ってプリプロセッサのスーパーセットになってるの?
m4 は m4 ですが何か?
sendmail の設定に使ったことあるな・・・
GNUのgccってperlのスーパーセットになってるの?
m4マクロってCのプリプロセッサとは関係ないのね。
プリプロセッサのスーパーセットを目指したようなマクロ処理系って
ないのかな。
最低限のマナーって…
そんなに嫌われてるのか。
マクロプログラミングはご法度だろ。LISPじゃあるまいし。
642デフォルトの名無しさん:04/03/13 15:30
プログラミング言語C++第三版のP601に

void rotate_all(list<Shape*>& ls, int angle)
{
  for_each(ls.begin(), ls.end(), bind2nd(mem_fun(&Shape::rotate), angle));
}

とあり、Shape::rotetaは引数が一つということでした。
bind2ndは二番目の引数を固定化するという認識だったのですが、
なぜ引数が一つしかないShape::rotetaにbind1stではなくbind2ndなのでしょうか?
>>642
メンバ関数 Shape::rotate を呼び出すには Shape* 型の変数が必要。
第一引数には ls に入ってる Shape* 型の要素を指定し、第二引数で
Shape::rotate に渡す引数 angle を指定してる。
>>643
rotate(Shape*,int)のように振舞うということでしたか
ありがとうございました
こんちわ.自分は主に数値計算を背景として持っている人間なんですが,
効率を最優先にした上で,ソースレベルでの保守性・拡張性・再利用性を
最大限に享受したいと思って色々見て回った結果,
C++でのgenericあるいはgenerativeな手法が最適に近い解であると思って
ここにやってきたんですが,こういうmotivationの人間に
何か良いアドバイスがあれば教えていただきたい(見ておくべき話題・本など)んですが・・・
(そもそもこういうmotivationにgeneric/generative@C++が向いているのかも含めて)
>>645
そんな質問されてもなあ。駄目っていわれたら辞めるの?
自分で試して判断したほうがいいんでは?
>>645
ふつーに C++ のプログラムを組めるようになってから、Efficient C++,
Inside the C++ Object Model, C++ Templates ぐらい読んでみれば、
展望開けると思うが。
あうぅ,やはり自分でやってみろってことですね...すいません.

>646
なにぶん自分はめちゃくちゃ経験が浅いので,
経験のある方から何か有意義なことが聴けたらと思ったもので.
それと今の自分にはgeneric/generativeの良い部分しか見えてない気がするので・・・

>647
後ろ2つは読んだことないので,参考にしてみます.
>>645
template というのはマクロを文字列ベースから記号ベースに置き換えた物という性質が幸いして
インラインアセンブラとの相性もいいケースが多いんですよね。(中身がC++である必然性が無い場合が多いんですよ)
自分は再利用よりも徹底的に効率最優先なプログラムを書いています。
ポリシーなんかを使って保守性・拡張性・再利用性のあるコードも同時に仕込んでおいて
状況に応じて交換なんてなのも結構いけると思います。
650名無しさん@Vim%Chalice:04/03/15 02:11
>>645
おぉ、同志ですな。
とりあえず blitz++ & Pooma ってか PETE 辺りは見てみました?
後は blitz++ の作者の書いたdocumentで expression template とかの
話が書いてあるのがどっかにあったんですが、ちょっと探した感じでは
見付からず…適当に探してみて下さい。
本買うなら C++ Templates とか Generative Programming とかですかね。
651645:04/03/15 08:22
>650
これですよね.
http://www.osl.iu.edu/~tveldhui/papers/techniques/
これは私のバイブルというか,こっちの世界に引きずり込まれるきっかけになったdocumentです.
最初にこれを読んだときは驚くのを通り越して笑ってましたよ.
blitzなどは斜め読みしかしたことないですけど,boost::ublasには一通り目を通しました.
ただこの手のライブラリは読んであとは使うだけですね.再発明は無駄なだけですし.
ただtemplate meta programmingの考え方は限定的に応用はありそうですが.
あとは649さんがおっしゃるような感じで仕込んでいくのが適当なのかな.
アセンブリとの親和性ってところはピンと来ませんが,勉強しておきます.
STL
OTL
○| ̄|_
ワロタ
>>652
同志よ
Σ(゚Д゚;≡;゚д゚)
何をSTLごときで落ち込んでいるんだ・・・・・・・
656名無しさん@Vim%Chalice:04/03/16 01:03
>>651
uBLAS一通り…強者じゃ…参りますた…orz
>>655
いや、STLがOTLに見えて仕方がないという話。だと俺は思った。
ttp://otl.sourceforge.net/
OTLは実在するわけだが。
>>657>>658
なるほどOracleをC++で直接扱うためのテンプレート・ライブラリね。
STLの書法が他のライブラリに与えた影響は大きいな。
660デフォルトの名無しさん:04/03/17 19:24
vc6 STLport-4.6.1 boost_1_30_1 で、
stlportのiostreamライブラリをインクルードしてる状態で
boost::lexical_cast<浮動小数点>();
したら、例外発生するんだけどさ、そうなるの俺だけ?

しかたないから atofでも使うなり・・・。
>>660
どーゆー例外が発生するのさ?
あと、Boost を最新版にすると?
>boost::lexical_cast<浮動小数点>();
663660:04/03/18 09:14
>>661-662
boost_1_30_1->boost_1_31_0
に訂正。書きコミスでした。ってこれが最新リリースですよね?

boost::lexical_cast<double>(std::string("0.0"));
boost::lexical_cast<double>("0.0");
boost::lexical_cast<double>("1");
などなど。

キャッチした、bad_lexical_cast::what() は
exception : bad lexical cast: source type value could not be interpreted as target
そのまんまって感じが・・・。

stlportのライブラリ使わなければ例外出ないんですけど・・・。
664660:04/03/18 09:15
ぐは、下げてどうする。上げ
>>663
ソースあるんだからVC上でトレースすれば何かわかるんじゃない?
666660:04/03/18 10:22
num_get_float.cpp内の

double _Stl_string_to_double(const char * s) {
// Skip leading whitespace, if any.
const ctype<char>& ct = use_facet<ctype<char> >(locale::classic());

locale_impl.cpp
// Static member functions.
const locale& _STLP_CALL
locale::classic() {
// return _Locale_impl::_S_classic;
return *__REINTERPRET_CAST(const locale*, &_S_b_classic);
}
で、こけてるなぁ。

_S_b_classicのデータが全部0・・・。
どっかで初期化しないとあかんのかな?
そろそろ自分では限界が・・・。
というか、仕事しねーと。
VS.NET2003でboost使おうとしたら、インテリセンスが効かないんだけど
みなさんはどうですか?コンパイルは通るし普通に実行できるんですけどね…
>>667
うちでは効きまくってるが。
669デフォルトの名無しさん:04/03/18 12:14
>>660

num_get_float.cppの
double _Stl_string_to_double(const char * s) {

const ctype<char>& ct = use_facet<ctype<char> >(locale::classic());
で例外発生してる模様。
const ctype<char>& ct = use_facet<ctype<char> >(locale());
でビルドし直したら
663は通ったよ。ただし、これが正しいのかは確認してないので注意
670デフォルトの名無しさん:04/03/18 12:45
ディレクトリ構造などを表せるツリーコンテナってありませんか?
671660:04/03/18 12:45
>>669
ありがとうです。
これって報告済みなのかなぁ?
って、boostよりstlportの問題なんかなぁ。
672669:04/03/18 13:14
>これって報告済みなのかなぁ?
自分はしてないっす。
locale::classic()の話題があがってるがよくわからんかった。

>って、boostよりstlportの問題なんかなぁ。
stringstreamでも同じとこでこけてたからそう。
673660:04/03/18 13:22
まぁ、暇できたら、既出じゃないか調べて報告してみるかぁ。
といっても、β版もあるから、それもチェックしてからかなぁ。
>>668
うーん…なんでかなあ。原因がわからない。
なんか物によっては効くし、物によっては効かないって感じです
scoped_ptrは効くけど、shared_ptrは効かないってな具合で。
675デフォルトの名無しさん:04/03/19 13:42
要素の重複を許さない list や vector って作れないのでしょうか?
>>675
setは嫌ですか?
677デフォルトの名無しさん:04/03/19 13:50

↓のスレで馬鹿がオナニーしてます
http://sports5.2ch.net/test/read.cgi/base/1076476572/l50


てめえの趣味はてめえでホームページでも作ってやれ。
ここは公共の掲示板だ。オナニーする場所じゃねえ。


↑このコピペを書きむだけでいいです。協力おねがいします。
678675:04/03/19 13:50
setもつかったことがありますが、[]が使えないとか
不便な点があるんですよ。。。
我慢すれば委員ですが、なにか解決策が在ればと思いまして。
>>678
整列済みでないコンテナで重複を許したくない場合、
重複判定のためには全数探索するか別途整列済みインデックスか
ハッシュテーブルを作ってそっちで探索するしかないわけだが。
680675:04/03/19 14:13
>>679
それは分かるんです。検索が発生して構わないんです。
・・・自分がコードを書く手間が無ければ。
>>678
std::listも[]が使えませんけど。。。
push_back()の前にfind()してみるだけで済むのにその
手間も省きたいと?
>>675
>要素の重複を許さない list や vector って作れないのでしょうか?

「作れないのでしょうか?」と聞かれたら「作れる」と答えるわけですが、

>>679
>・・・自分がコードを書く手間が無ければ。

そういう場合は「標準でありませんか?」ではないかと。
ネタケテーイだな。
684675:04/03/19 14:54
言い方が悪くて誤解を与えてしまいました。すいません。
「作る」と言ったのは「コンテナを開発する」という意味ではなく、
「インスタンスを作る」という意味でした。

標準でありませんでしょうか?

# STLで独自の可変長配列等を作らなくてよくなったのですが、
# ちょっとしたユーティリティー関数的なものを山ほど
# かかえるようになってきてちょっと鬱。私だけ?
>>684
setで駄目な理由にある [] が使いたいというのはどういう用途?
列挙するのならイテレータを使うだけだから[]は不要なわけだが。
>>684
具体例を挙げてみれ。イメージが湧かん。
>>675

>>681
この「push_back()の前にfind()」ではダメな理由を教えれ。

ダメだとしたら「どういう風に動いて欲しいのか」を教えれ。
>>684
だから標準でやるとすればpush_back()する前に重複チェック
するしかなかろう?それともstd::vectorの中に入っている個々の
インスタンス同士を効率よく通信でもさせる方法でも探すしか
ない。
675じゃないが、シーケンス内の順序に意味があって且つ重複を許したくない、
とかいう場合はstd::setではだめだな。
いや、それより、「なぜ標準でstd::setやstd::mapは重複を許さない」
ようになっているかを考えてみる方が良い。

それぞれのコンテナの実装上の性質から、標準では「実行コスト
が十分に見合うだけのメンバ関数以外は故意にカットしている」
ことに注意。

std::vectorの重複不可push_back()ももちろん実装すれば簡単に
できたろうが、「なぜ標準で実装されていないのか」を考えれば
自ずと答えが見えるだろう。
あ、>>690>>688への追加レスです。
>>690
それから何がわかる?
俺にはせいぜい、「>>675がやろうとしていることはコストが高い」
という位しか読み取れないんだが。
>>692
ああ、それぐらいの意味にしか考えてないよ。
俺が思ったのは>>675さんは>>692さんの考えている事を
意識してないのではないかと思っただけ。
694675:04/03/19 15:33
コンテナ内で行われている要素の格納方法や効率はどうでもいいんです。

コンテナを使おうと思ったとき、要素の重複を許す/許さないは
プログラマにとって初めから分かってることですよね?
なので、 「std::vector<type*> typeVector;」というような
コードを書いたときにその1行から「要素の重複を許す/許さない」
ということが読み取れるほうがいいと思ったんです。

Lokiみたいな感じで、重複を許す/許さないのポリシーを
指定するような方法があればいいと思うんですが無理なようですね。

push_back()の前にfindを使うのも、忘れてしまう可能性もあるし、
ソースの至るところで似たようなコードを書くことになってしまいませんか?
いや、だからさ、重複するものをpush_back()したときに、どういう挙動をして欲しいの?

さらに言うと、
std::vector<int> a(3);
って書いたとき、各要素はどうやって初期化されて欲しいの?

さらにさらにいうと、
std::vector<int> a;
a.push_back(0);
a.push_back(1);
a[1] = 0; // ←ここ
って書いたとき、どうなって欲しいの?
>コンテナ内で行われている要素の格納方法や効率はどうでもいいんです。

こういう大事な事は最初から書いてくれよ(;´Д`)。

ポリシーを可能にするより全く別のコンテナにした方が良いと
思わない?
>694
じゃあ,Loki使えばええやん?って返答はやっぱダメかな?w
まぁ,結論から言えばそういうのは標準では提供されていないので
標準にこだわるなら諦めなさいってことですな.
>>694
findを忘れるっておい、(重複を許可する前提の設計である)vectorとかを
裸で使うつもりなら >>695さんの書くような穴がいっぱいだよ。
例えばstd:::vectorを元にして重複を許可しないようなコンテナ
を作れたと仮定すると、重複した途端に例外を投げるような
仕様で良いのか?なおさら泥沼化する一方だと思うが。
つーか、そもそも重複を許さないVectorクラスの場合T& operator[]()が実装不能だと思うが。
>>700
throw Duplicate_Error() www
どうせ効率を無視するなら、operator[]のあるsetを書くべきじゃないか?
>>702
要素の挿入によって格納される順番が変わる可能性のあるコンテナに、
operator[]を実装する意味があるかどうかは甚だ疑問だ。
704675:04/03/19 16:14
>いや、だからさ、重複するものをpush_back()したときに、どういう挙動をして欲しいの?
その場合は、追加されないで欲しいです。

VC付属のSTLだと

>void push_back(const _Ty& _X)
>{insert(end(), _X); }

のようになっていますが、

>void push_back(const _Ty& _X)
>{ if(! _Xが格納されているか)insert(end(), _X); }
>

のような実装だと期待通りです。
このあたりはsetと同じだと思います。

ちょっとコード見たけど、ひょっとしてLoki::AssocVectorの
insert()は重複を許さない仕様? 単に並び替えの有りのvectorかと思ってた。
ちょっと試してみます。
705675:04/03/19 16:16
と思ったら、AssocVectorはmap相当のもので、キーと要素を
ペアで格納するものだったんですね。失礼しました。
確かにそうだな。
setのiteratorはその辺どうしてるんだっけ。
>>706>>703へのレス
>>704
メンバ関数にするのは諦めて普通の関数にしなせえ。
>>706
全ての要素を定数と見なすことによって順序が変わらないように
している。その代わり変更を伴うアルゴリズムを呼び出す事が
できない。コンテナが用意するメンバ関数のみが使用できる。
上でsetはoperator[]からいやだとおっしゃっていますが,
そもそも本当に各要素を非負整数に対応付ける必要があるのか?を
もう一度自問してみることをオススメします.
もし本当にその要求があるなら702さんのやり方が私も最適だと思います.
もちろん,このsetのinsert/eraseはO(N)になります.
また最初にvectorにdataを突っ込んで,その後vectorの要素が変わらないような要求なら
全部のdata突っ込んだ後にsort -> uniqueが適当だと思いますし.
具体的な要求によって最適な実装も変わってくると思うのですが・・・
何だかとても久しぶりに標準STLのコンテナについて盛り上がって
いるようだな。今はEffective STLのような良書があるんだからまず
そういう本を読んでみたらどうだろう。
あ,すいません.710の話はもちろん標準コンテナのラッパーを書くことが前提になります.
713375:04/03/19 16:44
> 全部のdata突っ込んだ後にsort -> uniqueが適当だと思いますし.
そういえばこの方法もありますね。
用途によってはこれが手っ取り早い気がします。

要望としては、「コンテナの開発」を行わずに、標準の方法で
実現したかったのです。

みなさんの意見を参考にして、setを使うことにしました。
考えてみれば、[]はさほど重要でありませんでした。
>>713
>考えてみれば、[]はさほど重要でありませんでした。

ガッカリ。

ま、予想はしてたけどな。
715デフォルトの名無しさん:04/03/19 17:05
typedef float float3[3];

map<int,float3> MyMap;

なんて宣言してコンパイル通ったんですけど

float3 f;
MyMap.insert(make_pair(1,f));

と使おうとしたらコンパイルエラーが出ました。
これは違法ですか? mapじゃなくてpairの問題?

std::pair<int const ,float [3]>::second' : クラス、構造体、共用体のメンバは、初期化できません。

だそうです。
コンテナにはコピー生成可能で代入可能な型が必要。
単に構造体にくるむか、boost::arrayなどを使えばいい。
要素数3のあたり座標か何かのようだが配列が必要なのか?
struct float3 {
  float x,y,z;
}
>>715
float3 f, g;
g = f;

が出来ないのと同じ。
719デフォルトの名無しさん:04/03/19 17:18
>>716
RGBの色のつもりです。
いままで9割方のルーチンをこの形で実装してしまいました。
うーん、どうしよう。この部分だけ割り切って構造体に包もうか・・・。

struct color3{
float3 rgb;
};

ってな感じ?
便乗質問で悪いのですが
標準コンテナにdefault constructableでない型を入れるのは
標準として保証されていますか?
利用できる操作が限られるのは重々承知しています.
>>720
ちょっと考えるとデフォルトコンストラクタを必要としない操作は
動きそうだけど、標準では保証してないのでは。
ttp://www.kuzbass.ru/docs/isocpp/lib-containers.html#lib.container.requirements
>>719
struct color3 {
  float r;
  float g;
  float b;
}
>>720
標準はDefaultConstructibleというrequirementを定義していない上に、
20.1.4 Default construction[lib.default.con.req]で次のように述べている。

>The default constructor is not required. Cretain container class member
>function signatures specify the default constructor as a default argument.
>T() must be a well-defined expression(8.5) if one of those signatures is
>called using the default argument(8.3.6)

これを見た感じ、問題なさそう。
>>720

コンテナ要素に対する要求は
・コピー可能
・代入可能
だけです。

だから、OK。
725720:04/03/19 18:27
うぎゃ.見つけたのに先に書かれてしまいました.
ただ,自分が一番気になっているmap::operator[]に関するデフォルトコンストラクトの
要求事項が見つけられなかったんですが,どこにあるんでしょうか?
C++標準ライブラリ日本語版P161より

"代入の演算はすべて、要素の型のデフォルトコンストラクタ、コピー
コンストラクタ、代入演算子、デストラクタを呼び出す。"

だからまずいのではないかと思う。標準に書いてないのだから
仕方ないかもしれんが。自己責任でお願い。
>>726
std::map::operator[]はキーがまだ存在しない場合は新しい
要素の型がデフォルトコンストラクタによって初期化される
ので、デフォルトコンストラクタを持たない型はコンパイル
エラーになると予想される。

標準では・・・・なかなか見つけられない(;´Д`)
標準では
ttp://www.kuzbass.ru/docs/isocpp/lib-containers.html#lib.associative.reqmts
を満たしている必要があるのではないかと。
>>727
23.3.1.2に、operator[]は(* ((insert(make_pair(x, T()))).first)).secondを返すと明記されてるから
エラーになることは間違いないと思われる。
ただし、mapに入れること自体の是非はわからない。
730720:04/03/19 18:47
あ,ありました.
http://www.kuzbass.ru/docs/isocpp/lib-containers.html#lib.map.access
皆さんお手数おかけしました.っていうか思いっきりすれ違いでした.申し訳ないです.
今更ながら規格書の必要性を痛感したので,18ドル出して規格書買おうと思います.
皆さん,どうもありがとうございました.
って,リロードしたらまた先に書かれていました.(´・ω・)ショボーン
>>730
18ドル? 安いな。旧規格(1998)のほうか。
>>731
ダウンロード版は安いらしい。
ttp://www.techstreet.com/cgi-bin/detail?product_id=1143945
std::stringとstd::ropeの比較を行ってみた。

#include <iostream>
#include <string>
#include <rope>

int main()
{
 std::string str;
 std::crope rop;

 std::cout << "std::string max size = " << str.max_size() << std::endl;
 std::cout << "std::crope max size = " << rop.max_size() << std::endl;

 try {
  while (true) str += "a";
 }
 catch (...) {
  std::cout << "std::string = " << str.length() << std::endl;
 }

 str.reserve(); // string shrink

 try {
  while (true) rop += "a";
 }
 catch (...) {
  std::cout << "std::crope = " << rop.length() << std::endl;
 }
}
stringとropeは用途が違うだろ
MinGW(gcc3.3.3)+STLPort4.6.1 WindowsXP Pro SP1+1GB+1.5G Swap
std::string max size = 4294967294
std::crope max size = 1836311902
std::string = 469762048
std::crope = 452108920

ropeが禿げしく遅い。コンパイラによってはropeの方が大きな領域を
確保できるものもあるようだが、MinGW+STLPortではstringの方が
結果が良かった。
>>734
Effective STL P216にropeの用途が書いてあるね。
begin()とend()はconst_iteratorを返す、か。内部はどのように
なっているのか興味がある。
ropeは代入、連結、部分文字列の取得に優れているとあるので、
今度は倍々にしてみた。

try {
 while (true) str += str;
}

のような感じ。

std::string max size = 4294967294
std::crope max size = 1836311902
std::string = 536870912
std::crope = 2147483648

今度はropeが上回った。この原因は一体何なのでしょうか?
s
tringはHDDのスワップは無しに終わったが、ropeはHDDの
スワップしまくりで実行に10分もかかってしまった。ストライ
ピングが必要だな・・・・
>>734-735
一文字更新ってropeが一番不得意とする操作なんで、その比較はフェアじゃないだろう…。
文字列コピー・substr・途中へのinsertを頻繁に使うのでないとropeの意味はない。
>>738
なるほど、エディタのような用途にropeは向いているのですか。
stringは確かに先頭に1文字insertするだけで本体を1バイト後ろへ
ブロック転送だからな・・・・

非常につまらないネタで済みませんが、燃料投下と言うことで
許してくれたまへ。
>>739
> なるほど、エディタのような用途にropeは向いているのですか。
知らずに比較しようとするなよ。初心者が>>734-735見ると混乱するだろ。
>>740
最初は
ttp://www.wakhok.ac.jp/~sumi/stl/header/rope.html
だけ見ていたのでてっきりropeは「長い文字列を扱うのに向いている」
のかと思ってました。

googleでぐぐってみてもあまりropeについて詳しいサイトはないですね。
STLPort HELPのrope(英文)を読んで勉強します・・・・・
C++ Templatesを読んでいろいろと試してみているのですが、
次のコードが通らないのはびっくりしました。

#include <string>

// note: reference parameters
template <typename T>
inline T const& max (T const& a, T const& b)
{
 return a < b ? b : a;
}

int main()
{
 std::string s;

 ::max("apple","peach"); // OK: same type
 ::max("apple","tomato"); // ERROR: different types
 ::max("apple",s); // ERROR: different types
}
>>742
 ::max("apple","tomato"); // ERROR: different types

同じ型に見えるなあ。
>>743
でしょ?でしょ?
その理由は"apple"と"peach"の型が char const[6] であるのに、
"tomato"の型は char const[7] だからなんですって。

で、参照でない引数だとそれは通るんです。(あまり著作物からの
直接引用は好ましくないんですけど、あまりにも香ばしいのでつい)

#include <string>

// note: nonreference parameters
template <typename T>
inline T max (T a, T b)
{
return a < b ? b : a;
}
int main()
{
std::string s;

::max("apple","peach"); // OK: same type
::max("apple","tomato"); // OK: decays to same type
::max("apple",s); // ERROR: different types
}
つーか>>744は当たり前ですね。配列がポインタに変換される
だけですた。
詳しい方教えて下さい。
テンプレートの特殊化についてなのですが、template <>を
付けなくてもコンパイルは通りますが、template <>を付けた
場合と付けない場合はどう意味が違うのでしょうか。

#include <string>

template <typename T1, typename T2>
class A {
 T1 t1;
 T2 t2;
};

template <> // ここ
class A<std::string, double>
{
 std::string str;
 double d;
};

int main()
{
}
747デフォルトの名無しさん:04/03/21 17:12
こういう使い方っていいのでしょうか?

#define DEF(type,name) \
template <typename type> class name \
{ \
};
DEF(int,def1)
int main(){}

VC7.1(OK)
VC6(NG)
GCC3.3.1(NG)

(boost/type_traits/detail/bool_trait_def.hpp)
で使われてるぽい。
VC7.1では

template <typename int> class def1
{
};

これが通るの?
通っちゃいけないと思うんだけど。


> (boost/type_traits/detail/bool_trait_def.hpp)
> で使われてるぽい。

マクロの中身も、使い方も違うとおもわれ。
749747:04/03/21 18:04
>>748
>マクロの中身も、使い方も違うとおもわれ。
DEF(T,def1)
ですね。(これなら他のコンパイラでもコンパイルできました。)

>VC7.1では
>template <typename int> class def1
>{
>};
>これが通るの?
>通っちゃいけないと思うんだけど。
通りました。
>>746
もしクラスでなくて関数だったら、template <>の有る無しで
特殊化バージョンか関数のオーバーロードか違ってくるが、
クラスの場合は正直違いがわからん。同じ意味じゃないのか?
>>749
そのとき、 def1 は何になるんだろう?

template<int> class def1; と同じかな?(def1<1>とか試せばわかりそう)
そうなると、 typename int が elaborated-type-specifier になってるっぽいな。
それって、間違い、だよね?
752747:04/03/21 19:24
>>751
DEF(int,def1)の場合、

std::cout << typeid(def1<1>).name() << std::endl;
で class def1<1>
と表示されたので、おっしゃるとおり
template<int> class def1;
と解釈されてるみたいです。

>そうなると、 typename int が elaborated-type-specifier になってるっぽいな。
>それって、間違い、だよね?
私には分かりません...(でも間違えてそうな予感)
> そうなると、 typename int が elaborated-type-specifier になってるっぽいな。

これが正しいとすると、 int を置くことができる箇所全部で typename int が使えるはず。
ふつうのローカル変数とか、
 typename int i = 0;
でも通るのかな?(VC7.1持ってないからわかんない)
>>753
エラー。

c:\Documents and Settings\*****\My Documents\Visual Studio Projects\
Typename\Typename.cpp(8) : error C2899: 型名はテンプレート宣言の外側
で使用できません。
>>754
ふむ、では、
template< typename T > int f() { typename int i = 0; return i; }
これだとどうだろう?
興味があったらまた試してみて。

それにしても、エラーメッセージの翻訳がクソだな。
>>755
おやすいご用。そいつは通った。
757747:04/03/21 21:12
template<float> class test_f{};
template<double> class test_d{};
とかもコンパイルできるみたい...。
>>756
ありがとう。
VC7.1はなにか文法定義が間違ってるんだろう。
コンパイルが通るか?のテストはしてるだろうけど、
コンパイルエラーになるか?のテストは難しいからねぇ。

>>757
それは、たぶん拡張じゃないかな?
拡張だとしたら、役に立つ機能だとは思う。
拡張機能オフのオプションがあるはずだから、そっちでエラーになればVC7.1は無罪。
>>758
Microsoft C/C++ の拡張機能にはtemplateやtypenameに
関する拡張はないです。
>>758
References Supported as Nontype Template Parameters
というのがVC7.1には存在しています。

The following sample works in Visual C++ .NET 2003 as specified in the standard:
// references__supported_as_nontype_template_parameters.cpp
extern "C" int printf(const char*,...);
template <int & ri> struct S
{
S()
{
printf("ri is %d\n", ri);
}

~S()
{
printf("ri is %d\n", ri);
}
};

int i = 1;

int main()
{
S<i> s;
i = 0;
}
>>760
そいつはちょっと違うのではないかと。
>>760
"as specified in the standard"とあるとおり、それは拡張じゃなくて標準。
「いままで抜けてましたけど」ってことだろう。
761の言うとおり、今の話の流れには関係ない。
763デフォルトの名無しさん:04/03/22 17:48
std::bitset で作ったビット列を、BYTEの配列にコピーしたいのですが
どのような方法がありますか?
自前?
>>763
std::bitsetはイテレータを持たないのでアルゴリズムが使えない。
その代わりoperator[]によるアクセスが可能なので、いくらでも
コピーはできる。

ところでBYTEにパックしたいのか、1BYTEに1bitでよいのか、
そこら辺がはっきりしない。
765763:04/03/22 18:30
あ、イテレーター無いんですね。気付きませんでした。
8bit単位で、BYTEにパックしたいと思っています。
766デフォルトの名無しさん:04/03/22 19:48
>>765
to_ulong()で渡すっていうのはダメ?
gcc 3.3.1 on Cygwin なんですが、以下のコードが通りません。
なんとか動かないもんでしょうか・・・。
lambda と function 併用している時点でかなり動作は怪しいですがw

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>

void a (void) { std::cout << 10 << std::endl; }
void b (void) { std::cout << 20 << std::endl; }
void c (void) { std::cout << 30 << std::endl; }

int main (int argc, char *argv[]) {
  std::vector< boost::function<void(void)> > v;
  v.push_back(a);
  v.push_back(b);
  v.push_back(c);
  std::for_each(v.begin(), v.end(), boost::lambda::_1.operator()());
}
>>765
それならメンバ関数size()でビット数を取得した後operator[]で
1ビットずつ取り出し通常通りパック。

>>766
bitsetのビットパターンがunsigned longで表現できる大きさを
超えていたらstd::overflow_errorが投げられるよ。
>>767
_1() の代わりに bind<void>(_1) でいける。
ドキュメントの 5.4.1. Nullary lambda functors and ret 辺りを嫁。
>>769
済みません。まだ通らないのです。

void a() { std::cout << 10 << std::endl; }
void b() { std::cout << 20 << std::endl; }
void c() { std::cout << 30 << std::endl; }

int main () {
 std::vector<boost::function<void ()> > v;
 v.push_back(a);
 v.push_back(b);
 v.push_back(c);
 std::for_each(v.begin(), v.end(), boost::bind<void>(boost::lambda::_1)());
}
C:/MinGW/boost/function_and_lambda1.cpp: In function `int main()':
C:/MinGW/boost/function_and_lambda1.cpp:17: error: invalid use of void
expression

C:/mingw/include/boost/lambda/detail/lambda_functors.hpp: In member function `

RET boost::lambda::placeholder<1>::call(A&, B&, C&, Env&) const [with RET =
boost::tuples::null_type, A = const boost::tuples::null_type, B = const
boost::tuples::null_type, C = const boost::tuples::null_type, Env = const
boost::tuples::null_type]':
C:/mingw/include/boost/lambda/detail/lambda_functors.hpp:143:
instantiated from `typename T::sig<boost::tuples::null_type>::type boost::lambda::lambda_functor<Base>::operator()() const [with T = boost::lambda::placeholder<1>]'
C:/mingw/include/boost/bind.hpp:148:
instantiated from `R boost::_bi::list0::operator()(boost::_bi::type<R>, F, A&) [with R = void, F = boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, A = boost::_bi::list0]'
C:/mingw/include/boost/bind/bind_template.hpp:21:
instantiated from `typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()() [with R = void, F = boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, L = boost::_bi::list0]'
C:/MinGW/boost/function_and_lambda1.cpp:17: instantiated from here
C:/mingw/include/boost/lambda/detail/lambda_functors.hpp:65: error: invalid
application of `sizeof' to an incomplete type
C:/mingw/include/boost/bind.hpp: In member function `R
boost::_bi::list0::operator()(boost::_bi::type<R>, F, A&) [with R = void, F
= boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, A =
boost::_bi::list0]':
C:/mingw/include/boost/bind/bind_template.hpp:21:
instantiated from `typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()() [with R = void, F = boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, L = boost::_bi::list0]'
C:/MinGW/boost/function_and_lambda1.cpp:17: instantiated from here
C:/mingw/include/boost/bind.hpp:148: error: return-statement with a value, in
function declared with a void return type
773765:04/03/22 22:23
> それならメンバ関数size()でビット数を取得した後operator[]で
> 1ビットずつ取り出し通常通りパック。

すいません。、「通常通り」ってどうやるんですか?
>>770
#include <boost/lambda/bind.hpp>
for_each(v.begin(), v.end(), bind<void>(_1));
>>774
ありがとうございました。無事動きました!てっきりboost::bindと
ばかり思っていました。boost::lambda::bindがあるとは・・・・もっと
boostのDOCをよく読みます。

>>773
ビット列が逆順になるけど例えば次のようにしたらどうでしょう。
#include <iostream>
#include <bitset>
#include <windows.h>

#define N 100

int main()
{
 int i;
 std::bitset<N> bt;

 for (i = 0; i < N; i++)
  bt[i] = std::rand() % 2;

 std::cout << "bitset<" << N << "> : " << bt << std::endl;

 BYTE by[20] = {0};

 for (i = 0; i < bt.size(); i += 8)
  for (int j = i; j < i + 8 && j < bt.size(); j++) {
   by[i / 8] <<= 1;
   by[i / 8] |= bt[j];
  }

 std::cout << "Packed BYTE serials : ";
 for (int j = 0; j < i / 8; j++)
  std::cout << std::bitset<8>(by[j]) << ' ';
}
関係ないけど最後の2行は

#include <iterator>
#include <algorithm>

を入れて

std::copy(by, by + i / 8, std::ostream_iterator<std::bitset<8> >(std::cout, " "));

と書くとスマートかも。
778デフォルトの名無しさん:04/03/22 23:52
みなさん、おもしろいもんができてますよ。
http://boost-sandbox.sf.net/libs/fsm
チュートリアルに日本語pdf有り。
相変わらず変態的でつね。
780デフォルトの名無しさん:04/03/23 16:42
std::string に多文字コード(Shift-JIS,UTF8,UTF16,EUCなど)を
格納、編集できるようにしたテンプレートなんて都合のいいもの、ありませんよね?
>>780
typedef basic_string <char> string;
typedef basic_string <wchar_t> wstring;
なわけだが。
782780:04/03/23 17:46
それを使って、文字コード変換できるの?
>>780
若干話それるけど、文字コードの変換には
http://tricklib.com/cxx/ex/babel/
を使わせていただいている。


784780:04/03/23 18:59
>>783
良さそうですね、bebel。
実行環境の文字コードに合わせて自動的に変換を行ってくれるような機構は
なさそう(?)なので、それくらいは自分でやろうと思います。
環境変数LANGでも見れば?Windowsは良く分からんけど。
786472:04/03/24 01:01
テンプレート引数がdouble型かどうかをチェックするのに
下のような関数をつくったのですが
dataが常にintに評価されてしまい、falseしか返ってきません。
どうしてでしょうか?

template<typename T>
bool IsDouble()
{
double a=3.3;
T data=(T)a;
return (double)data==a;
};


int main()
{
bool a=::IsDouble<short>(); // false
bool b=::IsDouble<double>(); // これもなぜかfalse
}
>>786
そのプログラムの誤りを指摘するのは不毛なんで避けるが
とりあえずこうするのが正解。

template<typename T>
bool IsDouble()
{
return false;
};

template<>
bool IsDouble<double>()
{
return true;
};
788786:04/03/24 01:15
>>787
レスどうもです。関数のアドレスをみたところIsDouble<short>も
IsDouble<double>も同一のアドレスで、別のインスタンスとして
生成されてないみたいです。何が原因なのでしょう(TT
789786:04/03/24 01:27
VC6だったのですが、VC7.1だと通りました。
わけがわからないです。
未熟さついでに786のコードのヘボさも指摘いただけると
嬉しいです。
>>789
どこが悪いという問題じゃないから
型変換に何を期待しているのかわからんが
そもそも変換が存在しないものもあるんだぞ? その場合コンパイルすらできないだろ

型を比較する方法は静的に解決するならテンプレートの特殊化が常道
標準ヘッダ<limits>でも読んでみるといい
791786:04/03/24 01:44
>>790
あっ、そのとおりです。初心者でヘボくてすんません。
どうもありがとう...
792(ログ補完):04/03/29 10:44
792 名前: デフォルトの名無しさん 投稿日: 04/03/25 17:51
 STLportのフォーラムが読めなくなっているのですが、
 私だけでしょうか?中身が空です。

793 名前: デフォルトの名無しさん 投稿日: 04/03/26 00:05
 横槍すまそん。もまいら教えてくさい。
 VC++6.0なのですが、これってtemplateと相性が
 わるいのですか?

794 名前: デフォルトの名無しさん [sage] 投稿日: 04/03/26 00:19
 >>793
 お話にもなりません。VC++2003を買いましょう。

795 名前: デフォルトの名無しさん [sage] 投稿日: 04/03/26 00:52
 >>794
 やっぱり...(TT

796 名前: デフォルトの名無しさん 投稿日: 04/03/26 11:40
 boost::format使おうとしたんだけど、
 vc6で、stlport使わない場合は通るのに、
 なんで
 stlport使うときに
 #define _STLP_NO_OWN_IOSTREAMS 1
 を定義するとコンパイル通らないんだ!
 #define _STLP_USE_STATIC_LIB
 なら通るんだけどな・・・。

797 名前: 796 [sage] 投稿日: 04/03/26 12:17
 std::basic_stringbuf
 の、ネームスペースをうまく認識してくれないっぽい。
 なんとかならんかなぁ。
ログ差分にレス付ける時は
>>現在のレス番.差分のレス番 (>>697.716)
見たいにやった方がわかりやすいかもな。

あと、これ以降のログもってるヤシは、補完よろしこ。
794ログ補完:04/03/29 21:20
798 デフォルトの名無しさん sage 04/03/26 12:40 ID:
#include <boost/mem_fn.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <vector>
#include <algorithm>

class TEST {
public:
 void fun0() {
 std::cout << "fun0" << std::endl;
}
 void fun1(double a) {
 std::cout << a << std::endl;
}
};

int main(void)
{
 std::vector<TEST> test(10);
 std::for_each(test.begin(),test.end(),boost::mem_fn(&TEST::fun0));
 std::for_each(test.begin(),test.end(),boost::bind(boost::mem_fn(&TEST::fun1),_1,10)); //←ここ
}

←の部分をもっと簡単に記述できないでしょうか?例えば、
std::for_each(test.begin(),test.end(),boost::mem_fn(&TEST::fun1)(10));
と書けると楽でよいのですけども。
795ログ補完:04/03/29 21:22
799 デフォルトの名無しさん sage 04/03/26 12:46 ID:
>>794.798
boost::bind( TEST::fun1, _1, 10) ); と記述出来るはずだが?

800 デフォルトの名無しさん sage 04/03/26 12:59 ID:
>>795.799 ありがとうございます。出来ました。
mem_fnにばかり目がいってました。なるほど〜。
で、ちょっと質問。試しに
std::for_each(test.begin(),test.end(),boost::bind(TEST::fun0,_1));
std::for_each(test.begin(),test.end(),boost::mem_fn(TEST::fun0));
を試してみたらどっちもいけました。どちらがイイのですか?
struct C{
template<typename IteratorT>
void print(IteratorT first, IteratorT last){
cout << string(first, last) << endl;
}
};

int main(int argc, char * argv[]){
C c;
string str("Hello, world!!");
//void (C::* p_fn)(string::iterator, string::iterator) = &C::print<string::iterator>;
boost::bind(&C::print<string::iterator>, c, _1, _2)(str.begin(), str.end());
return 0;
}

↑のコードが通らないんですけど理由が分かる方いらっしゃいませんか?
コメント行を入れて,bindの第1引数をp_fnに変えれば動くのですが・・・
>>796
g++3.2(MinGW)で通った。
798797:04/03/30 15:25
嘘だった。ゴメソ。
-Eオプションつけてたよ。
書き忘れていましたが,796はVC++7.1で試しました.(これが一番重要な情報でした.申し訳ないです.)
取ろうとするメンバ関数ポインタがtemplateのものでなければ796の書き方で通るのですが・・・
さらにgcc3.2.2で試したところ,今度は別の問題が出ました.
bind(...)(arguments)の形で呼び出せないようです.
結局,VC++7.1とgcc3.2.2の両方で通る書き方は以下でした.(mainの中だけ)

C c;
string str("Hello, world!!");
boost::function<void (string::iterator, string::iterator)> f;
void (C::* p_fn)(string::iterator, string::iterator) = &C::print<string::iterator>;
f = boost::bind(p_fn, &c, _1, _2);
f(str.begin(), str.end());
return 0;

もう少し楽というかスマートな方法は無いものでしょうかね?
というか,VC++7.1でなぜ796の書き方が通らないのかが分かれば問題解決なんですが・・・
>>798
まずエラーメッセージを貼ってみてください。

gcc3.3.1で通らない理由を詰めていくと、↓の問題に行き着いたようです。
だれか、このコードをVC++7.1で試してもらえるとありがたいです。

template< typename T > void tf( T& t );
void f() { tf( 1 ); }

2: error: could not convert `1' to `int&'
1: error: in passing argument 1 of `void tf(T&) [with T = int]'

ちなみに、
template< typename T > void tf( T const& t );
の宣言があれば(置き換えでも、追加でも)通ります。
>>800
VC7.1で試してみた。
c:\Documents and Settings\*****\My Documents\Visual Studio Projects\
Template1\Template1.cpp(10) : error C2664: 'tf' : 1 番目の引数を 'int' から 'int &' に変換できません。
'const' に対してではない参照は 非左辺値へバインドできません。

という事で予想通りリテラル値はconstでないと受けられない。
>>799
bind云々って言うよりも単に
(c.*(&C::print<string::iterator>))(str.begin(),str.end());
がコンパイルできない。g++3.2.2でもダメ。
overloadされた関数のアドレスは直接使用できないみたいな
仕様がある模様。799の解決案みたいな方法でポインタを一回
代入してoverloadの解決をしなきゃならないみたい。
template関数も同じ扱いなのかな?

以下の組み合わじゃダメ?
template<typename IteratorT>
struct C {
void print(IteratorT first, IteratorT last){
cout << string(first, last) << endl;
}
};
boost::bind(&(C<string::iterator>::print), &c, _1, _2);
803800:04/03/31 03:08
で、毎度のこと、規格を漁りにいってみました。

問題の箇所は、 14.8.2.1 Template argument deduction です。
まず、テンプレート引数の推測に使われる型は、実際に渡された型 int const から const が外れた、 int になります。
基本的にはこの型がテンプレート型引数にそのまま当てはまるケースを探して推測が行われます。
ただし、「そのまま」でなくてよいケースが3つあり、その一つとして
"If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be more cv-qualified than A."
という記述があります。
これを読む限り、 tf( T& ) に対して T = int const という推測は可能であるようです。
ですが、それに続いて、
"These alternatives are considered only if type deduction would otherwise fail. "
「これらの選択肢は、それ以外の推測が失敗したときにのみ考慮される」
とあります。

gccもVC7.1も、両方とも、
tf< int > を想定した時点で「引数の推測は成功」したとみなして実体化し、
あとは通常どおり呼び出しコードをコンパイルしようとしてエラー、
というシナリオが予想できます。

引数の推測が成功したとみなすタイミングを、
テンプレートの実体化の成功から、
さらに呼び出しコードのコンパイルとするか、
どちらが正しいのかは、調べがついていません。

VC7.1で bind(...)(str.begin(),str.end()) が通るのは、
一時オブジェクトで非const参照を初期化できるから、ではないかと思います。
804660:04/03/31 14:32
誰かフォーラムに登録してくれた?
"STLP 4.6.1 locale::classic()._M_impl is zero"
http://www.stlport.com/dcforum/DCForumID6/1565.html

なんやら、cvsで直ってるみたい?
VC7.1+STLport-4.6.1で、boost-1.31.0入れようとしてるんだけど
bjam "-sTOOLS=vc7.1-stlport"でビルド上手くいった人いる?
エラー吐きまくりッス
レス番が混乱しているようなので・・・
C::printのアドレスを取ろうとしている者です.(自分は799のつもり)
標準の(13.4)を読む限りでは,overloadされた関数のアドレスをとる場合
castによって選択するのが正しいようです.

bind((void (C::*)(string::iterator, string::iterator))&C::print, &c, _1, _2)

ポインタを一時的な変数に入れるのも,要はこのcastをやっているのと等価です.
&C::print<string::iterator>の形はGCCの独自拡張みたいですね.
bind(...)(str.begin(), str.end())が通る通らないの問題は
803さんのおっしゃるとおりだと思います.
色々,お騒がせしました.
で,また新たに問題がw
799にあるようにbindで生成されるfunctorをfunctionに代入したいのですが,
VC++7.1だと799のコードがうまく動きません.(コンパイルは通る)

function<void (string::iterator, string::iterator)> f;
f = bind(...);
assert(f); // VC++7.1だとなぜかfailする.(fにfunctorが代入されていない)

gccでは問題なく動きます.これについて誰か原因が分かりませんか?
function2<void, string::iterator, string::iterator>も試しましたが同じでした.
>>805
> エラー吐きまくりッス
エラーメッセージ晒せよ。
809807:04/04/01 22:39
>>807
これ,自己解決しますた.
http://article.gmane.org/gmane.comp.lib.boost.user/5313
マネージ拡張のbugみたいです.nativeのC++だと無事に動きました.
boost::shared_polymorphic_downcastを使おうと思ったんだが、
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
(適当な訳:shared_*_cast名は非難される。代わりに*_pointer_castを使え。)
とかコメントに書かれている。
でも、対応する*_pointer_castは存在しない。
(´・ω・`)

こんなとき、皆さんならどうしますか?
>>810
そのコメントどのファイルに書いてある?cast.hppには見当たらない
ようだが。(boost1.31.0)
>>810
static_pointer_castかdynamin_pointer_castだよな・・・。
polymorphic_downcastはないんだよなぁ・・・。

>>811
shared_ptr.hpp
Templeteって、なんのメリットあるのよ?
ちゃんとしたOOの「Object」みたいな「最も一般的な型」がないから
コンパイル毎に実装を生成してごまかしてるだけじゃん。
やっぱり釣りなのかなあ
>813
イタタタタタ・・・
ふふふ。
真を付かれて、ごまかしのレスしかできないようだな。
Templeteのメリットなんて、強いて挙げてもコンテナの中身の型が保証できる程度だろ?
++はごまかしが好きだねぇ(w
( ゚д゚)ポカーン
何をごまかしてるんだろうな(笑)
結局ひとつもTempleteのメリットを挙げられないのかよ。
中身のない煽りばかり。ププ
「最も一般的な型」を避けられるだけで十分メリットといえると思うが。
>819
なにはともあれ燃料投下ごくろうさん
この調子で1000までがんばってね
>>820
「最も一般的な型」を避けるのがどうメリットよ?実際、コンテナの中身が決まる程度じゃん。
templateを理解していない悪寒
釣りに決まってるだろ。世の中にこれほど頭の悪い奴がいるわけがない。
春休み終わったと思うんだけどな。。。
http://pc5.2ch.net/test/read.cgi/tech/1079460996/35
他所でスルーされたからってそうひがまなくてもw

まぁとはいえ,指摘されてるとおりgeneric containerなんてマクロによるけち臭い
コード生成テクニックの域を出てないんじゃない?
そして一般の人には「template≒STLのcontainer」ぐらいの認識が関の山だから
templateはすっぱいブドウだ,なんていわれても仕方ない部分はあるかもね.
ただ,generic containerなんてtemplateという名前に秘められた壮大な世界の
ほんの小さな一角に過ぎないのに,それだけを見て短絡的に評価を下されるのは
とても悲しいことだけどね.
++がそんな間抜けな設計のわけねぇだろ。
ちゃんと計算されてる。角度とか。
をいをい、C#にtemplateがないために苦労している人間が
ここに一人いるわけだが。
Policy 、Traits 、コンパイルタイムプログラミング、不必要な実体化の抑制、
コンパイル時にエラーがでる等等のすばらしい利点が理解できない阿呆はカエレ



とつられてみる。
>>828
次期バージョンには入る予定ッス。
>>829
そのコンパイルエラーがもう少し読みやすければ…と
g++3 / vc7使いは嘆く。
g++2, vc6よりはずっとマシなんだけど。

個人的には組込型への対応が、地味に嬉しい。
速度が低下しない。万歳。Object派生で実現出来ない物の一つ。
ただ、コンパイルが遅い罠。3GHZ級マシンつかいてー。
> そのコンパイルエラーがもう少し読みやすければ…と
そんな>>831に、boost::concept_check
>>832
Penitum4 3.2G使ってますけど、boostは相変わらず重いです。
gccでは特に。VC7.1ならプリコンパイルヘッダが効いているのか
二回目以降は割と快適。

gcc3.4ブランチが早くリリースされて欲しい今日この頃。
835デフォルトの名無しさん:04/04/10 00:46
>>833
あと STLFilt 超おすすめ
836828:04/04/10 10:02
>>834
ペンチアム2、500M、VC6だよ、とほほ。うちのマシンのほうがはえーよ。
>>836
開発用に会社で一括して買うマシンは低スペックだよね〜。
それになかなか買ってあたらないし。データは原則として
ローカルに置いちゃいけないしよぅ。

コンパイル時間で茶を飲めるような配慮がされているんでは
ないだろうか、と思う。下手に速いマシンだと茶を飲む暇も
ないよ。
838デフォルトの名無しさん:04/04/11 20:33
stlport4.6.2
age
>>837
じゃぁ感謝しないとね。
>>837
まとめた文の時間帯で遊びたい・・・。
ってか、中途半端な時間でストレスたまるだけだよぅ。

>>838
変更点ってどこに書いてあったけか?
>>840
_threads.hのタイムスタンプが新しくなってるね。マルチスレッドで
バグでもあったのだろうか。

もうgccとVC7.1でビルドしてしまったが。
・・・・と思ったらstl_msvc.hも新しくなってる。
ちょっと気になるな。
>>840>>842

The following changes were made in 4.6.2 since 4.6.1 release:

* threads.h:447 - fixed _NOTHREADS compilation error (thanks Wu Yongwei)

* stl_solaris.h - fixed pthreads compilation error

* stl_msvc.h : # define _STLP_HAS_SPECIFIC_PROLOG_EPILOG added for VC7.1

* locale_impl.cpp : locale::classic() initialization fixed
ちょいと気になったのですが、Loki::AssocVectorに
reserve()がないのは、何故なのでしょう?

アプリケーション起動時に生成され、
以後ほとんど変更されない連想配列に使おうと
思ったのだけど……。

挿入にかかる時間が大きいから、reserve()があっても
あまり速くはならない、ということなのかしら。
845840:04/04/12 19:07
>>843
ありがと
質問です。templateクラスを作ってメンバ関数からアルゴリズムを
呼び出そうとしたらうまくいかなくて困っています。

templateクラスでなければうまくいくのですが・・・・
次にプログラム片を載せます。
847デフォルトの名無しさん:04/04/14 19:44
template <typename T>
class A {
 T a[10];
 void func() {
  std::generate_n(a, 10, std::bind1st(std::mem_fun(&A<T>::gen), this); // 通りません(ToT)
}
 T gen() {
  return T(1);
 }
public:
 A() { func(); }
 void show() {
  std::copy(a, a + 10, std::ostream_iterator<T>(std::cout, " "));
}
};

int main()
{
 A<int> a;
 a.show();
}
あ、よく見たらtemplate無しでも通らないっぽい。
849デフォルトの名無しさん:04/04/14 20:54
std::generate_n(a, 10, boost::bind( boost::mem_fn(gen),this ));
とか
書いてから間違いに気づく
よくあることさ
>>849
やはりboostを使わないといけないみたいですね。標準のバインダ
で何とかしようとしていましたが無理なのかなあ。取り敢えずあり
がとうございます。

>>850
STLについては一通り理解したつもりだったのですが、クラスの
内部で使ったのは初めてでした。メンバ関数の呼び出しをクラス
内から行うのがネックでした。
便乗質問です。
bind1st,bind2ndはBinaryFunctionからUnaryFunctionに変換することができるわけですが、
>>847のようなケース、つまり、UnaryFunctionからGeneratorに変換するためのアダプタって
標準には無いのでしょうか?
要するに標準ライブラリにはunary functionからnullary function
(boostの造語.無項関数のこと)へのbinderが無いってことですか?
なんちゅー不便な.ちうかほぼ必須じゃないですか.ちゃんと用意しとけよーヽ(`Д´)ノ

>>852
私がTC++SLや規格書を漁ってみた限りではそれらしきものは発見できませませんでした.
boost::bind使っておけということなのでしょうね.
こうなるとC++のSTLは次期C++の改訂であちこち改変される
ヨカン・・・・というよりboostとかBlitz++を取り入れるだけだと
思うが。
>>853
んー、1項関数から無項関数への binder って、その1項関数(オブジェクト)に内部状態が
ある場合じゃないと有りがたみがないよね?
引数が変わらないで結果の変わるものじゃないと関数オブジェクトとして渡す意味がなさそうだし。
結果が同じなら、例えば >>847 の場合なら、std::fill_n(a, 10, gen()); みたいに別の方法がありそう。
ま、>>847 は、あくまでも例で実際はもっと違うコードなんだろうけど。
で、引数側を固定して内部状態の方が変化する、というのはそんなになさそうな気もするんだけど
どうなんだろ?
>>855
たとえばgen()が自前の乱数発生関数とか。
>>855
確かにおしゃっる通りだと思います.
そしてそれが標準に無項関数へのbinderが用意されていない理由だと邪推しています.
ついでに,標準のfunctorに対する姿勢として
「functorに状態を与えるのはあまりオススメできない」
というのも節々に感じられますし.ただここら辺は細かく議論しだすときりがないかと.
もちろん,私も847さんのコード(設計)にはだいぶ違和感を感じますが,
実際のコードには諸々の事情でunaryを束縛して気軽にnullaryとして使いたいという
事情も起こりえるだろうとは思います.
858デフォルトの名無しさん:04/04/18 06:46
何で毎度毎度typeって定義するんだ?
たとえば・・

template <class T>
class A{
typedef T type;
。。。。以下略

外から見るためって認識でいいのかなぁ・・
でもたまにprivateでやってたりするしな・・
それともTが長く複雑になったりしたときに
見やすくするってことかな・・
859デフォルトの名無しさん:04/04/18 07:04
俺はタイプ数節約するために書いてたけど、
他に理由あるのか?
便乗で質問。
まさか、
std::vector<int> hoge;
for (const int * it = hoge.begin(); it != hoge.end(); ++it){ ... }
とか書いてるんじゃないよな?
ちょっと考えたら分かるでしょ。
なんでわざわざtypedefしてるかくらい。
template <typename T>
struct ZeroPolicy {
 typedef T value_type;
 ZeroPolicy() {}
 static T get() { return static_cast<T>(0); }
};

template <typename T>
struct RandomPolicy {
 typedef T value_type;
 RandomPolicy() {}
 static T get() { return static_cast<T>(rand()); }
};

template <class _ValuePolicy>
struct ValueCreator {
 typename _ValuePolicy::value_type;
 /* typedef typename _ValuePolicy::value_type value_type; だっけ? */
 _ValuePolicy::value_type get() { return _ValuePolicy::get(); }
};

ValueCreator< ZeroPolicy<int> > a;
ValueCreator< RandomPolicy<int> > b;

適当な上に無意味な例だが、こういう時にも使うってことで。
ただ、このコードこのまま通るとは思わんでくれ。
俺も自信ないからw
862858:04/04/18 09:24
メタプログラミングによくあるような
templateのクラスを関数にみたてて
戻り値ならぬ「戻り型」みたいなイメージで利用してる
ってことでいいのかな
連書きすまそ。

ってことはprivateで宣言してるのは
変数だったら

class A{
private:
int i
}

って書くところを型を入れる"変数"として

template <class T>
class A{
private:
typedef T i;
}

って書いてるってことか・・・
なんかわかりやすかった。ありがとん
>863
その場合、typedefいらんよ。
template <typename T>
class A {
private:
T i;
};
でOK。

privateで宣言してるtypedefは、クラス内部での記述量を減らす目的で使ってるだけだと思う。

template <typename T1, typename T2, typename T3>
class A {
A<T1, T2, T3> & operator+= (const A<T1, T2, T3> & rhs) { return *this; }
};

template <typename T1, typename T2, typename T3>
class A {
typedef A<T1, T2, T3> class_type;
class_type & operator+= (const class_type & rhs) { return *this; }
};
>>860
ものによってはコンパイル通らないですしねぇ、これ。

>>862
よくメタ関数って呼ばれてまふ。

#typedef templateが早く入ればいいのににゃあ・・・あと、v.iteratorって書き方も・・・
template<typename T> typedef T* add_ptr<T>;
template<typename T> typedef T* add_ptr<T*>;

vector<int> v;
for(v.iterator it=v.begin(); it!=v.end(); ++it){...}
866865:04/04/18 15:07
あ、間違えました。すいません。

誤:template<typename T> typedef T* add_ptr<T>;
正:template<typename T> typedef T* add_ptr;
867デフォルトの名無しさん:04/04/19 22:33
BCB6で boost::mt19937 使えてますか?(1.31.0)
static const 周りでバグってるみたいなんですけど。
>>867
普通に使えてるよ。BCC5.6.4。
#include <iostream>
#include <boost/random.hpp>

int main()
{
 boost::mt19937 mts;

 for (int i = 0; i < 100; i++)
  std::cout << mts() << ' ';
}
869デフォルトの名無しさん:04/04/20 07:19
>>868
distributionを使うとダメみたいなんです。
documentに書いてあるサンプルの↓

http://www.boost.org/libs/random/index.html
boost::mt19937 rng;
boost::uniform_int<> six(1,6);
boost::variate_generator<boost::mt19937, boost::uniform_int<> > die(rng, six); ←ここ
int x = die();

ここで Access Violation になっちゃいます。
他のgeneratorなら大丈夫なので、使い方は合っていると思うんだけど。
どうやら static const の初期化がうまくいっていないような……(調査中)

http://boost.sourceforge.net/regression-logs/cs-win32.html
で random_test が Fail になってることと関係があるのかな。
>>869
俺の環境では(WindowsXP SP1+BCC5.6.4)、Access Violation
にならずに何のエラーも出さずにvariate_generator()を呼び出した
時点で正常終了してしまう。

gcc3.3.3やVC7.1だと動くねえ。
typedef GenScatterHierarchy< TYPELIST_3< double, double, double> > AAA;

int main(void)
{
AAA aaa;
for ( size_t i( 0 ); i < Length<AAA>::value; ++i )
{
Field< i >( aaa ) = i;
}
}

Field< i > で怒られますが何か手はありませんか?
>>871
何がしたいの?
エラーメッセージは?
まぁとりあえずiがその書き方じゃコンパイル時に決まらんからそりゃ
template の引数に渡したらコンパイル出来ない罠。
ただ、その前に(Lokiを使ってるんだと思うが)かなーり間違ったコードに見えるが…
やりたい事は、

double tmp0( 0 );
for ( size_t i( 0 ); i < size; ++i )
{
tmp0 += C[0] * a[0][i];
}

double tmp1( 0 );
for ( size_t i( 0 ); i < size; ++i )
{
tmp1 += C[0] * a[0][i] + C[1] * a[1][i];
}

double tmp2( 0 );
for ( size_t i( 0 ); i < size; ++i )
{
tmp2 += C[0] * a[0][i] + C[1] * a[1][i] + C[2] * a[2][i];
}

のforループを計算するクラスの自動生成です。
>>871
struct f {
AAA& aaa; f( AAA& aaa ) : aaa(aaa) {}
template<class T> operator()(T) {Field<T::value>(aaa) = T::value;}
};
using namespace boost::mpl;
for_each< range< size_t<0>, Length<AAA> > >( f(aaa) );

Lokiは使ったことないから知らんが、何でその用途でGenScatterHierarchyしてんの?
>>875 >>874をやろうと試みた一環です。
さらに、質問します。
Barton Nackman trickをサーチして以下のコードを見つけました。
このようなコードはどういった文脈で使うことを想定しているのでしょう?

#include <iostream>
template< class T_mesh >
class Mesh {
public:
Mesh() {
Dimension = asLeaf().getDimension();
std::cout << " Mesh: Dimension = " << Dimension << std::endl; }
~Mesh() {}
T_mesh& asLesf() { return static_cast<T_mesh&>(*this); }
protected:
size_t Dimension;
};
template< class T_number, size_t Dim >
class StructuredMesh : public Mesh< StructuredMesh< T_number, Dim > > {
public:
StructuredMesh() {
Dimension = Dim;
std::cout << " StructuredMesh: Dimension = " << Dimension << std::endl;
}
~StructuredMesh() {};
size_t getDimension() { return Dim; }
};
int main( void ) {
StructuredMesh<double, 3> grid;
return 0;
}
878デフォルトの名無しさん:04/04/21 14:57
>>877そのコードの出自がはっきりしないと文脈って言われても難しいな。とりあえずどこにあったコード?まぁ数値計算でメッシュを構築して何かをするんだろうなぁってのは分かるけど。
>>876
自己言及なtemplateの事かなぁ。
使用状況としては仮想関数を使用せずに機能追加をしたい場合とか。
但し877の例は自己言及なテンプレートの例としてはいまいちな感じ
がするので"Barton Nackman trick"=="自己言及なtemplate"なのかは
自信ない。
>>879
> 自己言及なtemplateの事かなぁ。
yes.っていうか、877みたいな使い方か、あとせいぜいfriendを使って
グローバル関数を定義する技くらいしか自己言及的templateの使い方を
俺は知らないんだけど、他にどういうのがあるの?

>>876
> このようなコードはどういった文脈で使うことを想定しているのでしょう?
class Mesh { …自分自身を返すasLeaf()メソッドを実装… };
class StructuredMesh : public Mesh { … };
class HogerattaMesh : public Mesh { … };
class FunyarakaMesh : public Mesh { … };

StructuredMesh g1; g1.asLeaf(); // StructuredMesh&を返すようにしたい
HogerattaMesh g2; g2.asLeaf(); // HogerattaMesh&を返すようにしたい
FunyarakaMesh g3; g3.asLeaf(); // FuntarakaMesh&を返すようにしたい
って思わないか?
>>使用状況としては仮想関数を使用せずに機能追加をしたい場合とか。
なるほどぉ〜。
>>871
typedef Tuple<TYPELIST_3(double,double,double) > AAA;
まあタプルはboostの方にもあるけど。
LokiのFunctorに関して質問します。

#include<iostream>
#include<algorithm>
#include<loki/Functor.h>
#include<loki/SmallObj.cpp>

template<size_t N>
class class1 {
public:
void voidfunc( void ) {std::cout << "class1 " << N << " func( void )" << std::endl;}
};

class class2 {
public:
void voidfunc ( void ) {std::cout << "class2 func ( void )" << std::endl;}
void sizefunc ( size_t i ) {std::cout << "class2 func ( " << i << " )" << std::endl;}
};

int main( void )
{
class1< 100 > test1;
class2 test2;

Loki::Functor< void >
cmd1( &test1, &class1< 100 >::func ); // エラー

Loki::Functor< void >
cmd2( &test2, &class2::voidfunc ); // O.K.

Loki::Functor< void, TYPELIST_1( size_t ) >
cmd3( &test2, &class2::sizefunc ); // O.K.

std::vector < Loki::Functor< void > > v;
v.push_back( cmd1 );
v.push_back( cmd2 );
v.push_back( cmd3 ); //エラー 変数をbindしたい。

for ( size_t i( 0 ); i < v.size(); ++i )
v.[i](); // O.K.

std::for_each ( v.begin(), v.end(), boost::mem_fn( Loki::Functor< void >::operator() ) );// エラー

}

のエラー部分の記述方法を御教授いただけないですか?
>>883
boost::functionとboost::bindを使った方がいいと思う・・・
・・・あれ、そいうえばコンパイラは?
BCB-Xです。
>>884
型が違うから、コンパイル通らない。
Loki::BindFirst を使いなさい。

v.push_back( Loki::BindFirst( cmd3, /*バインドしたい変数*/ ) );

バインドしたい引数が増えてきたら、Loki::Functor + コンテナをやめて、
Boost.Function, Boost.Bind, Boost.Signal に乗り換えると吉。
template<typename T>
class B{};

template<typename T>
class C{};

template<typename T>
class C<B<T> > : C<T>{};

こんなことして大丈夫でしょうか?
多分,大丈夫だとは思うのですが・・・
>>888
大丈夫
>>887 signal使うと幸せになれる気がしてきました。
有益な情報ありがとうございました。
>>879
C++相談室のほうで,friend関数の(宣言ではなく)定義をclass templateの
スコープ内に書くtrickのことをBarton-Nackman trickと呼んでいた者ですが,
"C++ Templates"ではこのように呼んでいたのでそうしていました.
で,この本にはさらに「このtrickはCuriously Recursive Template Pattern(CRTP)と
同時に用いられることが多く,CRTPが誤ってBarton-Nackman trickと呼ばれることが多い」
とありました.確かにCRTPのことをBarton-Nackman trickと呼んでいる人が多い
(877とか)ですが,厳密には違うということなんでしょう.細かいことですが.
うーむ、template は面白いですね。勉強になります。
で、昨日まで CRTP という言葉も知らなかった香具師が突っ込むのもなんですが、
Curiously "Recurring" Template Pattern が正しいみたいです。

>891
>friend関数の(宣言ではなく)定義をclass templateのスコープ内に書くtrick
これは、14.5.3/5 によりインスタンス化ごとに関数定義が行われるため、
関数 template ではないが同じ効果が得られて(゚Д゚)ウマーという認識で
いいでしょうか。

ただどちらかと言うと、>880 の言う
>あとせいぜいfriendを使ってグローバル関数を定義する技くらいしか
の方が、Barton Nackman trick が指すものに近い表現じゃないかと思うのですけど
どうでしょ?
ttp://www.informit.com/articles/article.asp?p=31473&seqNum=5
は C++ Template の抜粋のようですが、
>Barton and Nackman frequently used CRTP in combination with
> friend name injection (and the latter is an important component
> of the Barton-Nackman trick)
という表記があるのでそう考えてみました。

ところで、>891氏「CLANNADの渚タンってどうよ?」
893880:04/04/24 17:55
> で,この本にはさらに「このtrickはCuriously Recursive Template Pattern(CRTP)と
> 同時に用いられることが多く,CRTPが誤ってBarton-Nackman trickと呼ばれることが多い」
うっへ。ほんとだ、俺は思いっきり間違えてました。
言われてみればCRTPはBarton/NackmanよりはCoplienタンのオハコだもんなぁ。。。
>>892
>"Recurring"
両方の表現とも見かけますよ.

>14.5.3/5 によりインスタンス化ごとに関数定義が行われるため、
>関数 template ではないが同じ効果が得られて(゚Д゚)ウマー
はい.自分の意図はそうです.標準の該当項目引いてもらえて助かります.

>>あとせいぜいfriendを使ってグローバル関数を定義する技くらいしか
>の方が、Barton Nackman trick が指すものに近い表現
ですね.

>>Barton and Nackman frequently used CRTP in combination with
>> friend name injection (and the latter is an important component
>> of the Barton-Nackman trick)
>という表記があるのでそう考えてみました。
Barton-Nackman trickという言葉だけでは指しているものが曖昧になりますね.
以後,気をつけます.

>ところで、>891氏「CLANNADの渚タンってどうよ?」


>>893
でも,Todd VeldhuizenもBarton-Nackman trick == CRTPと解釈していて
正直,自分にもどの解釈が正しいか判断しかねています.
なのでCRTPと呼ぶのが一番誤解が少ないと思います.
Modern C++ Design の P. ixに記述されているコードを理解したくて
Barton Nackman でググって>>877のコードを見つけました。
どなたかこれを解説してください。
>>895
>>877は基底クラス(Mesh)から派生クラスのメンバ関数を呼び出すもので、
Modern C++ designのコードとは関係ない。

ところで、あの本のコードのどこが理解できないんだ?
m,l,tの意味とか使用例とか見たいなぁと思ってググったんです。
>>897
mは質量、lは長さ、tは時間だと思われ。
たとえば
typedef Physical<1, 0, 0> mass; /* 質量 */
typedef Physical<0, 2, -2> work; /* 仕事 */
typedef Physical<0, 1, -2> acceleration; /* 加速度 */
typedef Physical<1, 1, -2> force; /* 力 */

acceleration g(9.8); /* 重力加速度 */
force gravity = mass(4) * g; /* 質量と加速度をかけると力になる */
work fravity = mass(4) * g; /* エラー、単位が違う */
あ〜、なるほど。単位系で次元を指定しているのですね。
分かりました。有難うございます。
へー、このテンプレート素晴らしいなあ。
いい事教えてもらった。ありがと。
901デフォルトの名無しさん:04/04/27 19:45
boostのビルド方法を教えてください。
環境は、Visual C++ 7.1 + STLport 4.6.2。
これでboost 1.31.0をビルド・インストールしようとしています。

以下のように一部書き換えたvsvars32.batを実行して、
------------------------------------------------------
@set STLPORT_PATH=C:\STLport-4.6.2
@set STLPORT_VERSION=4.6.2
@set INCLUDE=%MSVCDir%\INCLUDE\stlport;%MSVCDir%\ATLMFC\INCLUDE;
%MSVCDir%\INCLUDE;%MSVCDir%\PlatformSDK\include\prerelease;
%MSVCDir%\PlatformSDK\include;%FrameworkSDKDir%\include;%INCLUDE%
@set LIB=%MSVCDir%\ATLMFC\LIB;%MSVCDir%\LIB;
%MSVCDir%\PlatformSDK\lib\prerelease;%MSVCDir%\PlatformSDK\lib;
%FrameworkSDKDir%\lib;%LIB%
------------------------------------------------------

bjam "-sTOOLS=vc7.1-stlport"
"-sBUILD=debug release <runtime-link>static/dynamic
<threading>multi <stlport-version>4.6.2"
"--without-python"

とやると、regex以外はビルドに成功するのですが、
902デフォルトの名無しさん:04/04/27 19:45
ライブラリファイルをインストール後、
http://www.kmonos.net/alang/boost/classes/posix_time.html
記載のコードが、LNK2019エラーとなって
ビルドできません。

date_timeのビルドでエラーは出ないものの、
どうも、time_from_string()など、
一部の関数がライブラリファイルに含まれていないようです。

どなたか、同じ環境で正常にビルドできた方、
ビルド方法を教えて頂けるとありがたいのですが。
>>902
ライブラリファイル自体を個別にリンク指定しないとリンク自体されんよ。
アルゴリズムで関数オブジェクトを多用し始めると、どうしても
標準C++のアダプタだけでは飽き足らなくなり、boostに手を
染めるというありきたりな結果に。でもいいや、boostはやめられん。
>>901
> @set STLPORT_PATH=C:\STLport-4.6.2

そのインストール場所なら、STLPORT_PATHはC:が正しい。
tools/build/v1/stlport.jam の get-stlport-root に付いてるコメント見れ。
906901:04/04/28 20:14
>>905
おかげさまでうまくビルドできました。
有り難うございます。

VSVARS32.BATを以下のように書き換える。

@set STLPORT_PATH=C:
@set STLPORT_4.6.2_PATH=C:\STLport-4.6.2
@set STLPORT_VERSION=4.6.2
@set INCLUDE=%MSVCDir%\INCLUDE\stlport;
    %MSVCDir%\ATLMFC\INCLUDE;%MSVCDir%\INCLUDE;
    %MSVCDir%\PlatformSDK\include\prerelease;
    %MSVCDir%\PlatformSDK\include;%FrameworkSDKDir%\include;%INCLUDE%
@set LIB=%MSVCDir%\ATLMFC\LIB;%MSVCDir%\LIB;
    %MSVCDir%\PlatformSDK\lib\prerelease;%MSVCDir%\PlatformSDK\lib;
    %FrameworkSDKDir%\lib;%LIB%

bjamのコマンド。

bjam "-sTOOLS=vc7.1-stlport"
     "-sBUILD=debug release <runtime-link>static/dynamic <threading>multi"
     install "--without-python"

>>903
リンクはちゃんとしていました・・・。
907デフォルトの名無しさん:04/04/28 22:07
>>907
よくわからないけど、違法コピーのアドバイス入れておきましたよ。
std::list< std::vector<T> >みたいなコンテナってないですかね?

at(pos)が 平均pos/VECTORSIZEで行われて、
erase(it)が、平均 N/(2*2VECTORSIZE)で行われる感じで。

std::dequeみたいな感じですが、dequeはeraseにO(N)かかってしまう
(かわりにatはO(1)で終わる)のでちょっと違うわけです。
>>909
SGI 版 STL の rope みたいなの?
コンテナとして定義しようと思ったら計算量がうさんくさいし、insertしたときの挙動もあやしい。
それに std::list< std::vector<T> > と書いた時点で簡単に実装できることが予想できる。

ないでしょうね。
912デフォルトの名無しさん:04/04/29 20:30
任意の長さの文字列リテラルを渡し、そのリテラルの各文字のASCII値の合計をcompile-timeに計算して
返すような関数テンプレートって実現できるでしょうか?

1. マクロはなるべく使わない(もしどうしても使うならBoost.Preprocessorで簡潔に)
2. 文字列長は最長32で文字程度に制限してもOK
3. アセンブリリスト上でループ処理に展開されているのはNG, mov $256, %eax みたいに即値になってるのキボン

って感じで考えているんですが、どうも私の書くコード(テンプレートで再帰)はg++ -Sするとループ処理に展開
されちゃってまして、即値になるようなコードが思いつかず難航してます。お知恵を拝借したく。

g++ 3.3.x を使ってます。
>>912
コンパイル時に文字列リテラルから文字コードの値を取り出すことすらできないんじゃないの?
そのうえ制限つけちゃなおさら無理だろ。
>>913
いや文字の値を取り出すことくらいはできるだろ。例えば

template<int LEN> inline int Foo(const char (&s)[LEN]) {
return s[0] + s[1] + s[2];
}

は恐らく
> mov $256, %eax みたいに即値になってる
こういう状態になる。LENをつかってねえけどw
最適化で消えればいいなら、↓でいけるみたい。

#include <cstddef>

template< std::size_t N >
inline int sum( char const (&array)[ N ] )
{
 &sbsp;return sum( reinterpret_cast< char const (&)[ N - 1 ] >( array ) ) + array[ N - 1 ];
}
template<>
inline int sum< 1 >( char const (&array)[ 1 ] )
{
 &sbsp;return array[ 0 ];
}

int f()
{
 &sbsp;return sum("abcdefgasvnljgsthnbdcsxuijbnjikhdljklybuihdmctuldvugn");
}
ごめん。スペースミスった。

#include <cstddef>

template< std::size_t N >
inline int sum( char const (&array)[ N ] )
{
  return sum( reinterpret_cast< char const (&)[ N - 1 ] >( array ) ) + array[ N - 1 ];
}
template<>
inline int sum< 1 >( char const (&array)[ 1 ] )
{
  return array[ 0 ];
}

int f()
{
  return sum("abcdefgasvnljgsthnbdcsxuijbnjikhdljklybuihdmctuldvugn");
}
$ g++ -O2 -S -o - 916 && g++ -dumpversion && g++ -dumpmachine
.text
.align 2
.p2align 4,,15
.globl __Z1fv
.def __Z1fv; .scl 2; .type 32; .endef
__Z1fv:
pushl %ebp
movl $5663, %eax
movl %esp, %ebp
popl %ebp
ret
3.3.1
i686-pc-cygwin
918916:04/04/29 22:00
で、特にへんなことはしてないんだが、>>912の書いた「テンプレートで再帰」はなぜループになったんだろう?
もしかして、最適化をかけていなかっただけ?
>>918
末尾再帰の最適化にでもなったのかも?
920912:04/04/30 00:30
>>918
g++って、inlineと明示的に書かないと-O2でもインライン化してくれない
(ことがある?)んですね。そのせいでした。

でも色々参考になりました(reinterpretのとことか)。
ありがとうございました。
921デフォルトの名無しさん:04/04/30 00:37
前レスで話題に出てるけど解決してないようなのでもう一度質問させてください。
boostを用いると、VisualStudioのインテリセンス(オートコンプリート)が効きません。(しかし、ものによっては効いたりする)
どうやらうまいことマクロをかいてインテリセンスを騙してやるとうまくいくらしいのですが
それ以上のことが自分の力不足からわかりません。
もしわかる方いらっしゃいましたら教えてもらえませんか(涙
>>921
インテリセンスなんかに頼るな。
923デフォルトの名無しさん:04/04/30 01:22
>>916
inline int sum(char const (&array)[N])

ここ、&無しにできないの?
>>922
それをいっちゃあおしまいだよ・・・
>>923
C++Primer第3版P526参照。参照型にしないと、テンプレート引数に
配列の大きさを表す第2引数が必要になる。これは関数内では配列
の大きさを知る事ができないという問題を解決する。但しNが異なる
テンプレートのインスタンスを呼び出すと、その度にインスタンスが
作られてしまう。

本を読むと一種の慣例法のように使うみたいな書き方がしてある。
926916:04/04/30 02:14
>>923
int sum<1>(char const array[1]);
int sum<2>(char const array[2]);
とすると、関数の型が両方とも int (char const*) に変換されてしまうので、
template引数の推測などが使えなくなってしまう。
927デフォルトの名無しさん:04/04/30 02:19
>>926
そこを何とか・・
928916:04/04/30 02:32
>>927
&無しにすることに何の意味があるの?
>>927
だから配列の大きさを表す第2引数をテンプレート引数に
付け加えるしか手がない。
こうでもするしかあるまい。54をstrlen()なんかにするとコンパイルが
通らない。

template <std::size_t N>
inline int sum2(char const* array)
{
 return sum2<N - 1>(array + 1) + *array;
}

template <>
inline int sum2<1>(char const* array)
{
 return *array;
}

int f2()
{
 return sum2<54>("abcdefgasvnljgsthnbdcsxuijbnjikhdljklybuihdmctuldvugn");
}

int main()
{
std::cout << f2() << std::endl;
}
#define SUM2(X) sum2<sizeof(X)-1>(X)
でも足しとけ。
932デフォルトの名無しさん:04/04/30 12:42
>>928
いや、つける意味がないからさ、&は。
無駄なものは取りたいじゃない。
過去のしがらみでつけなきゃならんというのは分かった。
933デフォルトの名無しさん:04/04/30 17:50
ないの?
>過去のしがらみでつけなきゃならん
なら、
>つける意味が
「ある」って事やん。
>>934
厨はいちいち出てくるなよ。
>>932
いやだから・・・・&は無駄じゃないって。つけないとコンパイル
通らないでしょ?
>>936
&はシンタックスシュガーなんだからさ…
もういいてば。
>>937
それは無茶じゃないかな。きみの構文糖の定義は?

>>937
>&はシンタックスシュガーなんだからさ…
初耳です。&を取って通るコードの例を示して下さい。
>>937

> 358デフォルトの名無しさん04/04/30 18:42
> gccのoptionてアホだよな

> 359デフォルトの名無しさんsage04/04/30 18:58
> >>358
> 日本語書くときに促音を省略してしまうキミもね。
個人的には関数テンプレート+最適化で対応するより、スクリプトでも組んでテーブル作るほうが
素直じゃないかと思う。
942デフォルトの名無しさん:04/05/01 00:09
>>939
正気ですか。
>>942
配列の場合は&を付けないとポインタに変換されてしまい、
配列の大きさの推測ができないだろう。それもどうでもいいから
何か例をお願いします。
>>942
横槍だが、ただ例を出せばいいだけなんじゃねーの?
この手の流れになると突っ込まれた方は必ず逃げるよね。何でだろ?
>>944
脳内で「できる」と思っていても実際やってみるとコンパイルが
通らず「やーめた」となるからだろう。俺もC++を十分に理解し
ているとは到底言えないが、少なくともコンパイルが通る事を
確認してから発言するようにしている。
946デフォルトの名無しさん:04/05/01 00:49
ついに>>945は知能障害を起こしますた。

いいから例を出せってw
変なのが一匹いるみたいだが放置で。
>>946
ん?>>945=>>943=>>948ですよ。
>>942が早く例を出してくれるのを待ってるんですが。
バカっぽいな。
>>946=>>949恥ずかしいのかな?失敗は誰にもあるよ。気にすんな。
&の意味も知らずに可哀想。
お前ら、もちつけ。
釣られるやつも釣る奴と同レベルだぞ。
荒らしに脊髄反射してるのも荒らしと大して変わらんことに気づけ。
&は山椒
鰻丼に山椒かける?
かけるよ

template/* ここスペース入れる?俺は入れるんだけど */<...>
956デフォルトの名無しさん:04/05/01 04:15
>>954
で、鰻以外の何に山椒かける?
>>956
麦茶に混ぜると美味しいよ。
958デフォルトの名無しさん:04/05/01 12:19
>>955
そこに入れるということは、
int main (int argc, char *argv[]);
とか書くのか?やめてくれ....orz
>955
俺はスペース一個入れる

>958
誤爆?勘違い?
テンプレートクラス/関数を書く時のスタイルの話だよ?
>>955
俺は入れないなあ。
理由聞かれても困るけど、少なくとも>>958みたいなことは全然考えてないよ。
templateと<の間に空白があるってのは、
属性として密接に関連付いた記号なのに分離されてる感じで違和感が・・
>>958もそうだし、あと配列変数名と [ の間が開いたときも同じように気になりそう。
んじゃ、
for/* ここにはスペース入れる? */(;;)
if/*ここはどうよ?*/()

漏れは、
template< typename HOGE > class AGE {};
for ( ; ; ) {}
if () {}
963デフォルトの名無しさん:04/05/01 14:52
俺はこう

template<typename HOGE>
class AGE
{
};

for (i=0; i<10; ++i)
{
}

if (hoge > fuga)
{
}
吾亦紅
965955(いいだしっぺ):04/05/01 16:33
俺はこう

template <typename HOGE>
class AGE {
  ...
public:
  ...
};

for (i = 0; i < 10; ++i) {
  ...
}

if (hoge > fuge) {
  ...
}

int* piyo(const char* foo, double baz)
{
  ...
}
966デフォルトの名無しさん:04/05/01 17:03
俺はこう
template<typename HOGE>
class AGE{
・・・
}
;

for(
  i=0;
  i<10;
  ++i
){
・・・
}

if(
  hoge > fuga
){
・・・
}
967デフォルトの名無しさん:04/05/01 17:31
そんなことよりBoost本キタ━━━━━(゚∀゚)━━━━━!!
ttp://www.kmonos.net/wlog/38.php#_1245040501
Let's boostの人?
>>968
んだ。

Boostのバージョンはいくつかな?
970
>>970
どーでもいいが、痛いことやってると思う。
>>967
K.INABA氏GJ!
973デフォルトの名無しさん:04/05/02 02:15
c++相談スレから誘導されました
template<typename T>struct A
{
  char c;

  A(char arg): c(arg){}

  void test()
  {
    cout << c << endl;
  }
};

int main()
{
  A<int> a('1');

  A<string>* p = (A<string>*)(&a);

  p->test();
}
 
のようにクラス内でテンプレート引数を使用しないとして
テンプレート的に違う型のポインタにキャストするのって
動作は保証されてますか?
>>973
キャスト演算子をstatic_castにすると通らなくなる所から、
コンパイラ内部では別個の種類のオブジェクトのポインタ
と見なされているようだ。で、reinterpret_castにすると通る
が、移植性がないし保証がないだろう。(仕様書ではどの
当たりに出ているかな?)
975973:04/05/02 02:24
>>974
そうですか... 残念です
ありがとうございました
>>973
されない。
templateかどうかは関係なく、別クラスの同じ名前のメソッドを呼べるかという問題だね。
>>976の回答が微妙にズレてるような気がするのは俺だけ?
>>975
>>974さんも言ってるけど、C++使いなら、できるだけC型の古い
キャスト演算子の使い方はやめた方がいいよ。その方がバグが
出にくくなるから。

static_cast
const_cast
dynamic_cast
reinterpret_cast

面倒でも使い分けよう。boostにも他にいくつかcastがある。
>>977
そうだろうな。
>>973
恐らくそれがだめなのは、後からうっかりクラス内にTを使った
構文を導入してしまう事が多々あるからだろう。

それまで動いていたのに途端にだめになるのはおかしい。それ
なら初めから別の種類のクラスだと見なしておけという事では
ないだろうか。

vector<double>* vp;
vector<int>* p = (vector<int>*)&vp; とやったらだめなのは
直感的にわかるが、後からちょこっとクラス内を変更して、
全く別の所(クラステンプレートのポインタの相互変換)で
エラーが出てきたのでは、発見も遅れそうだ。
>>973>>980
class A() { void test(); }
class B() { void test(); }
つーことだtてば。
>>981
あぁ、何書いてんだろ…orz
A()とかの()はいらん。
>>973
class templateからinstantiationされて出来た各々のクラスは,
あらゆる意味で別の型(クラス)です.
従って,973さんがやろうとしていることはまったく関連の無い違う型への
キャストと同義であり,973さんが期待している動作の保証はまったくありません.

>>974
14.4あたりですかね?

それと976さんの表現で私は良いと思うのですが・・・どうなんでしょうか?
回りくどい書き方なので分かりにくいかもしれんが
>976の書いてる内容が真理をついてる
逆に言えば、一般のクラスと同様
クラステンプレートが共通のインターフェイス
class Testable {
virtual void test() = 0;
};
を継承するようにすれば望みどおりのことはできるってこったね。

しかしテンプレートと継承の使い分けで混乱する人は多いようだねぇ
とりあえず >973 がなぜそんなことをしようとしたのか、やりたいことはなんなのかを
書いた方がより有益なアドバイスが得られるんじゃないかと思う。
987デフォルトの名無しさん:04/05/03 01:20
誰か次スレ立てろな
俺はやらないから
俺 はやらないから
次スレ立てたよ。
【C++】template 統合スレ -- Part4
http://pc5.2ch.net/test/read.cgi/tech/1083550483/
>989
ご苦労!!
991デフォルトの名無しさん:04/05/03 18:33
http://boost.cppll.jp/HEAD/libs/mpl/doc/paper/html/intro.html#intro.whymetaprog
の、"1.3. Why metaprogramming?"で、突然にyaccの話が出てくるんですが、そこの意味/意図が掴めません。

どなたか簡単に補足説明ねがえませんでしょうか
>>992
1. Introductionの段階でYACCは出てきますが…。2行目の頭。
993デフォルトの名無しさん:04/05/03 20:43
>>992
ですね・・。すみません、質問を変えます。
1. We could write programs to interpret the metadata directly.
の、metadataってここでは具体的に何を指しているんでしょうか?
>>993
それも1のIntroductionに書いてある。太字で。
英語は苦手なんだが、このYACCの例ではEBNFでは無いだろうか。
テンプレート自体とは関係ない気がする。
995デフォルトの名無しさん
>>994
> 英語は苦手なんだが、このYACCの例ではEBNFでは無いだろうか。
ですね。

自分の知りたいことがうまく伝えられなくて本当に申し訳ないんですが、
えーと・・"1.3. Why metaprogramming?"の1.の例では、メタプログラミング
をしない場合にYACCでどう書けって言っているんでしょうか?

私の感覚ではall_permutations関数のシグネチャを適当に変えてnew[]
すりゃ終わりなんですが(遅さは別としてyaccなんていらない)。