【C++】template 統合スレ -- STL/Boost/Loki, etc.(2ちゃんねる)

FTP、CGI、SSI、telnetが自由に使える超高速レンタルサーバ。
工夫しだいで、楽しさ100倍。 www.binboserver.com
月額千円サーバ | サブドメインコース | BIGなサーバ

サブドメインコース:CGIやFTPが使いたい・お金を掛けたくない人のために。
 *****.syo-ten.com *****.gasuki.com *****.zansu.com
 お好きな名前を無料で使えます。早い者勝ち。

人気サイト 月額千円サーバ:.com .net .org で取得できます。.JPドメイン大歓迎!
 超高速・高機能サーバを1000円で!使ってみれば、分かります。

BIGなサーバ:Big なBig なサーバー。充実したサポートをお求めの方へ。
 インターネットでご活躍の皆様へ、そしてご活躍予定の皆様へ。
2ちゃんねるは、このサーバを使っているです。

■掲示板に戻る■ ■過去ログ倉庫めにゅーに戻る■

【C++】template 統合スレ -- STL/Boost/Loki, etc.
1 名前: デフォルトの名無しさん 投稿日: 02/11/20 21:29
C++ のジェネリックプログラミングの話をしましょう。
以下のスレッドを統合するスレです。

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

【C++】Boost使い集まれ!
http://pc3.2ch.net/test/read.cgi/tech/1033830935/

Generic Programming with C++ Template
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html

関連スレ、その他リンクは >>2-5 あたりに。


2 名前: デフォルトの名無しさん 投稿日: 02/11/20 21:29
関連スレ
C++相談室 part12
 http://pc3.2ch.net/test/read.cgi/tech/1035005882/

リンク
STLPort
 http://www.stlport.org/

boost
 http://www.boost.org/

Loki
 http://freshmeat.net/projects/lokilibrary/
 http://www.geocities.com/rani_sharoni/LokiPort.html

ISO/IEC 14882
Programming languages -- C++
 http://webstore.ansi.org/ansidocstore/product.asp?sku=ISO%2FIEC+14882%2D1998
 http://www.kuzbass.ru/docs/isocpp/


3 名前: デフォルトの名無しさん 投稿日: 02/11/20 21:31
重複スレで良いな?


4 名前: デフォルトの名無しさん 投稿日: 02/11/20 21:35
boost固有の話は boostスレでやってくれていいけど、いずれは
このスレに統合するってことで。


5 名前: デフォルトの名無しさん 投稿日: 02/11/20 21:39
>>1
乙カレー


6 名前: デフォルトの名無しさん 投稿日: 02/11/20 21:39
C++標準以外のものは使うな。よってSTLのみとする。


7 名前: デフォルトの名無しさん 投稿日: 02/11/20 21:48
スレ立ったの見て一瞬 (゚Д゚)ハァ? と思ったが、後で合流するならいいか。


8 名前: デフォルトの名無しさん 投稿日: 02/11/20 22:33
>>1-2
乙ー


9 名前: デフォルトの名無しさん 投稿日: 02/11/20 22:56
カレー


10 名前: デフォルトの名無しさん 投稿日: 02/11/20 22:57
boostに関する有名な日本語サイト

・boost info
http://user.ecc.u-tokyo.ac.jp/~g940455/wp/boost/

・Hattareme Programming
http://www.dodgson.org/lab/hat/

・Let's boost
http://www.kmonos.net/alang/boost/

・Regex
http://www.s34.co.jp/cpptechdoc/article/regexpp/

・Boostを使おう
http://www.emaki.minidns.net/Programming/tools/Boost/


11 名前: デフォルトの名無しさん 投稿日: 02/11/20 23:19

マターリ逝きましょう



12 名前: デフォルトの名無しさん 投稿日: 02/11/21 01:04
#include <memory>

class B {};
class D : public B {};

std::auto_ptr<B> f()
{
  std::auto_ptr<D> p;
  return p;
}

↑の一見通りそうだけど、エラーになります。
test.cpp:9: no matching function for call to `std::auto_ptr<B>::auto_ptr(
std::auto_ptr<B>)'
/usr/include/c++/3.1.1/memory:346: candidates are:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp>) [with _Tp = B]
/usr/include/c++/3.1.1/memory:216:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&) [with _Tp1 = B, _Tp = B]
/usr/include/c++/3.1.1/memory:203:
std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = B]
test.cpp:9: initializing temporary from result of `
std::auto_ptr<_Tp>::operator std::auto_ptr<_Tp1>() [with _Tp1 = B, _Tp = D]'

とりあえず、
  return std::auto_ptr<B>( p );
で、エラーにならなくなるようです。
この修正が妥当なんでしょうか?


13 名前: デフォルトの名無しさん 投稿日: 02/11/21 01:21
>>12
std::auto_ptrが継承に対応してないからかと思ったけど、どうも区別が
曖昧だというエラーが出るね。


14 名前: 投稿日: 02/11/21 02:13
なかなか難しいよね。templateベースのものは。
まあ仕事にも使った事はあったけど。便利なんだけど。


15 名前: デフォルトの名無しさん 投稿日: 02/11/21 02:54
継承は対応してないのか。確かに通らんね。

#include <memory>

class B {};
class D : public B {};

std::auto_ptr<B> f()
{
std::auto_ptr<D> p;
return dynamic_cast<std::auto_ptr<B> >(p);
}


16 名前: デフォルトの名無しさん 投稿日: 02/11/21 03:11
auto_ptr<B>とauto_ptr<D>は単に別の型であって、
暗黙の型変換ができなかった、ということでは?

>>15
そこでdynamic_castを思い浮かべてしまうというのは
ちと知識不足すぎやしませんか。ネタ?



17 名前: デフォルトの名無しさん 投稿日: 02/11/21 03:15
>>16
いや(汗、本当に継承に対応してないのかと思って。
でもパラメタの型が違うから当たり前か・・・・


18 名前: 12 投稿日: 02/11/21 10:55
>>16
ttp://www.kuzbass.ru/docs/isocpp/lib-utilities.html#lib.auto.ptr
↑には、
>template<class Y> auto_ptr(auto_ptr<Y>&) throw();
>Requires: Y* can be implicitly converted to X*.

>template<class Y> auto_ptr& operator=(auto_ptr<Y>& a) throw();
>Requires: Y* can be implicitly converted to X*. The expression delete get() is well formed.

っていうインターフェースがあるようで、
auto_ptrの規格は、>>12の最初のコードが
コンパイルできるように配慮されているように見えます。

同時に、余計な変換手段に見えるインターフェースもありますが・・・。


19 名前: デフォルトの名無しさん 投稿日: 02/11/21 11:56
よく読み直してみろ


20 名前: デフォルトの名無しさん 投稿日: 02/11/21 22:19
統合スレになったとたんレベルが...


21 名前: デフォルトの名無しさん 投稿日: 02/11/21 22:24
C言語スレみたいにバカをネタにしてつきあうぐらいの寛大さが必要です


22 名前: デフォルトの名無しさん 投稿日: 02/11/21 22:33
でも確かに、何でstd::auto_ptrにキャストオペレータ入れなかったんだろうとは思うね。


23 名前: デフォルトの名無しさん 投稿日: 02/11/21 22:35
std::auto_ptrってどんなメンバ関数があるのだろう?


24 名前: デフォルトの名無しさん 投稿日: 02/11/21 22:46
> std::auto_ptrにキャストオペレータ

作るとしたらどんなコーディングになる?


25 名前: デフォルトの名無しさん 投稿日: 02/11/21 23:05
template<class T, class U>
std::auto_ptr<T> cast(std::auto_ptr<U>& ref)
{ return std::auto_ptr<T>( ref.release() ); }
と、やりたいけど出来ないんだよな


26 名前: デフォルトの名無しさん 投稿日: 02/11/21 23:13
そうじゃなくて、自分がauto_ptrの設計者だとしたら。


27 名前: 12 投稿日: 02/11/22 00:43
>>19
読み直してみたけど、新しく気づいたことはなかったです。

・・・やっぱりわからん。
<memory>を読んでみたけど、変換インターフェースの実装のところに、
「派生関係の変換が可能になるように、これらのモノが必要」みたいなコメントまで書いてある。
コメント中にあるサンプルと同様のコードをコンパイルしようとしたけど、
やっぱり>>12と同じエラーになる。

モッカイageテミル


28 名前: デフォルトの名無しさん 投稿日: 02/11/22 00:51
>>25
release()必要ないのでは?std::auto_ptrのコンストラクタは所有権を
移動させるから。


29 名前: デフォルトの名無しさん 投稿日: 02/11/22 00:54
auto_ptr<T>とauto_ptr<U>の互換性があるかどうか分からないのに、
どうやって所有権を移動させるんだ?


30 名前: デフォルトの名無しさん 投稿日: 02/11/22 01:50
継承と同じように考えて、親クラスのポインタ変数に子のオブジェクトのアドレス
を代入できるかと自然と考えてしまいました。でもstd::auto_ptrは継承とか考慮
してないので、エラーになるのですね。


31 名前: デフォルトの名無しさん 投稿日: 02/11/22 02:04
>>12
むしろ継承関係にあるからこそのエラーと思われ。
継承関係になかったら別のエラーになるけどさ。

gcc-2.95.3 でcompileしてみた。
conversion from `auto_ptr<D>' to `auto_ptr<B>' is ambiguous
: candidates are: auto_ptr<D>::operator auto_ptr<B><B>()
: auto_ptr<B>::auto_ptr<D>(auto_ptr<D> &)

>>29
互換性があればcompileできるだろ?


32 名前: 31 投稿日: 02/11/22 02:23
あぁ >>25 のままじゃcompileできんな
template<class T, class U>
std::auto_ptr<T> cast(std::auto_ptr<U>& ref, std::auto_ptr<T>&)
{ return std::auto_ptr<T>( ref.release() ); }
だね。

つーか、むしろ
template<typename T, typename U>
T cast(U &ref, T &) {return T(ref.release());}


33 名前: デフォルトの名無しさん 投稿日: 02/11/22 03:52
http://www.zdnet.co.jp/enterprise/0211/11/n20.html


34 名前: 12 投稿日: 02/11/22 07:33
>>32
そのテンプレート関数はどうやって呼び出すんだ?

template<typename Y> std::auto_ptr<X>::auto_ptr( std::auto_ptr<Y>& r );
template<typename Y> std::auto_ptr<X>& std::auto_ptr<X>::operator = ( std::auto_ptr<Y>& r );
template<typename Y> std::auto_ptr<X>::operator auto_ptr<Y>();
↑キャストなんて標準で装備されてるこれらで十分のはずだ。


35 名前: 31 投稿日: 02/11/22 11:01
>>34
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?



36 名前: デフォルトの名無しさん 投稿日: 02/11/22 13:11
2!



37 名前: デフォルトの名無しさん 投稿日: 02/11/22 13:31
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?



38 名前: デフォルトの名無しさん 投稿日: 02/11/22 13:31
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?
 え


39 名前: デフォルトの名無しさん 投稿日: 02/11/22 13:31
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?
  


40 名前: デフォルトの名無しさん 投稿日: 02/11/22 13:31
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?
>そのテンプレート関数はどうやって呼び出すんだ?
質問ですか?説明しなきゃいけないようなこと?
class B {};
class D {} public B {};
//class D {};
auto_ptr<B> b;
auto_ptr<D> d;
b = cast(d, b);
DがBを継承してなかったらどうなるか。

>キャストなんて標準で装備されてるこれらで十分のはずだ。
あ、そ。で、>>31 の内容は理解できましたか?
       


41 名前: デフォルトの名無しさん 投稿日: 02/11/22 13:37
>>31
通常時、TとUには互換性があるかも知れないが、
auto_ptr<T>とauto_ptr<U>に互換性があるときはT==Uの時だけだろ。


42 名前: デフォルトの名無しさん 投稿日: 02/11/22 16:59
一体このスレは何が起きているんだ?


43 名前: デフォルトの名無しさん 投稿日: 02/11/22 17:08
>>42
もう後には引き下がれない意地と意地のぶつかり合いが
繰り広げられています。



44 名前: デフォルトの名無しさん 投稿日: 02/11/22 20:11
異常なほど向きになっておりますな。
しかも会話がかみ合っていないときている。


45 名前: デフォルトの名無しさん 投稿日: 02/11/22 20:15
意見が噛み合ってないのは議論じゃなくて論破しようとしてるせい。


46 名前: デフォルトの名無しさん 投稿日: 02/11/22 20:15
ん?
とりあえず、前の発言者のレスを引用して、(゚Д゚)ハァ? とか書けばいいわけか?


47 名前: 12 投稿日: 02/11/22 20:16
>>31
器用な人ですな。

> で、>>31 の内容は理解できましたか?
え・・・?理解できません、たぶん。
あと、キャストする関数の引数が二つなのが理解できませんねぃ。


48 名前: デフォルトの名無しさん 投稿日: 02/11/22 20:16
> ん?
> とりあえず、前の発言者のレスを引用して、(゚Д゚)ハァ? とか書けばいいわけか?

(゚Д゚)ハァ?


49 名前: デフォルトの名無しさん 投稿日: 02/11/22 20:32
> > ん?
> > とりあえず、前の発言者のレスを引用して、(゚Д゚)ハァ? とか書けばいいわけか?
>
> (゚Д゚)ハァ?

(゚Д゚)ハァ?


50 名前: デフォルトの名無しさん 投稿日: 02/11/22 20:59
時期ヴァージョンのJava(J2SE1.5)でJavaGenerics(?)がコアAPIに統合されテンプレートが使えるようになり、コレクション系インターフェースの問題が
解消されるというのでちょっと期待しているのですが
C++でテンプレートを使うメリット、デメリットとはどんなものでしょうか?

投稿記事のC++ソースを見た感じ、複雑そうに見えます。
テンプレートを使いこなすには修行が必要そうですね。


51 名前: デフォルトの名無しさん 投稿日: 02/11/22 21:07
STL ライクなコードが Java で書けるというだけで、template が使える
というのとは違うと思っていたが気のせいか?


52 名前: 31 投稿日: 02/11/23 02:19
>>37-40
すげぇ、これこそまさにテンプレートなんだね。感心。

>>41
> auto_ptr<T>とauto_ptr<U>に互換性があるときはT==Uの時だけだろ。
いや。 >>18 とか >>34 にも書いてある。
それを、互換性がある、と言わないとか、
class B {}; class D : public B {}; のときは B == D というなら
そういうもんなのねとあきらめる。



53 名前: 31 投稿日: 02/11/23 02:20
>>47
> あと、キャストする関数の引数が二つなのが理解できませんねぃ。

#include <memory>
template<class T, class U> std::auto_ptr<T> cast(std::auto_ptr<U>& ref)
{ return std::auto_ptr<T>( ref.release() ); }

template<class T, class U> std::auto_ptr<T> cast(std::auto_ptr<U>& ref, std::auto_ptr<T>&)
{ return std::auto_ptr<T>( ref.release() ); }

class B {};
class D : public B {};
main() {
std::auto_ptr<B> b;
std::auto_ptr<D> d;
b = cast(d, b);
b = cast<B>(d);
}

でどうよ。



54 名前: デフォルトの名無しさん 投稿日: 02/11/23 03:26
これは通るけどこれでもいいの?

template<class T, class U> std::auto_ptr<T>
cast(std::auto_ptr<U>& ref)
{
return std::auto_ptr<T>(std::auto_ptr<U>(ref));
}


55 名前: デフォルトの名無しさん 投稿日: 02/11/23 03:36
>>54
その関数実際に呼んでみた?


56 名前: デフォルトの名無しさん 投稿日: 02/11/23 03:38
>>55 読んでみました。この通りです。

class A {
public:
int i;
};

class B : public A {
public:
int j;
B(int x, int y) { i = x; j = y; }
};

template<class T, class U> std::auto_ptr<T>
inline cast(std::auto_ptr<U>& ref)
{
return std::auto_ptr<T>(std::auto_ptr<U>(ref));
}

int main()
{
std::auto_ptr<B> ptr(new B(123, 456));
std::auto_ptr<A> pa;

pa = cast<A>(ptr);

std::cout << pa->i << std::endl;

ptr = cast<B>(pa); // ダウンキャストはだめ?

std::cout << ptr->j << std::endl;
}


57 名前: デフォルトの名無しさん 投稿日: 02/11/23 03:40
で、

pa = cast<A>(ptr);

は通るんですが、

ptr = cast<B>(pa); // ダウンキャストはだめ?

はだめなんです。もっとも、この行はrelease()を使った版でも
通りませんでした。


58 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:03
>>56-57
何、通るの!?

げ、STLportだと通るよ。

> ダウンキャストはだめ?
reinterpret_castしてるわけじゃなくて
pointerのoperator=だからねぇ。


59 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:07
>>58
gcc3.2でも通るよ。

>reinterpret_castしてるわけじゃなくて
>pointerのoperator=だからねぇ。

あっそうですね。考えてみればそうだ。


60 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:11
>>12 の話に戻るけどさ、

auto_ptr<B> p = auto_ptr<D>(); // (1)
p = auto_ptr<D>(); // (2)

g++ 3.1 で (1) が通らないんだけど、
誰か解説してくれ


61 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:14
>>60
auto_ptr<型>()はコピーコンストラクタだからじゃない?


62 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:30
>>60
スマソ。std::auto_ptr(T* p = 0) はコンストラクタだね。

ところで
std::auto_ptr<B> p = std::auto_ptr<B>(std::auto_ptr<D>());
は通るよ。


63 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:33
んー、ということは、std::auto_ptrの代入演算子とコピーコンストラクタの
書き方に対称性がないということになるね。


64 名前: 60 投稿日: 02/11/23 04:39
あとね
auto_ptr<D> d;
auto_ptr<B> b0(d); // OK
auto_ptr<B> b1 = d; // NG
なのよ。

auto_ptr<B> b2(auto_ptr<D>());
はfunction declarationになっちゃうからいいんだけど。



65 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:44
>>64
それは、std::auto_ptrのコンストラクタがexplicit宣言されている事と
関係があると思う。


66 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:47
つまり、

auto_ptr<B> b0(d); // OK

の時はコンストラクタを呼び出してくれるけど、

auto_ptr<B> b1 = d; // NG

の時はコピーコンストラクタが呼び出されてしまい、それが
buggyなのでエラーになるかと。違うかもしれんけど。


67 名前: デフォルトの名無しさん 投稿日: 02/11/23 04:59
いろいろ調べてみたら、std::auto_ptrには

template class<T>
operator std::auto_ptr<T>()

という変換演算子があるらしい。この格好がコピーコンストラクタと
酷似しているため、コンパイラが混乱してしまうようだ。

だから明示的にコピーコンストラクタを呼び出してやればいいと思う。


68 名前: デフォルトの名無しさん 投稿日: 02/11/23 05:10
最初の

#include <memory>

class B {};
class D : public B {};

std::auto_ptr<B> f()
{
std::auto_ptr<D> p;
return p;
}

に戻ってみると、return p; の時点で、
std::auto_ptr<D>をstd::auto_ptr<B>にコピーするコピーコンストラクタを
呼び出すか、std::auto_ptr<D>をstd::auto_ptr<B>に変換する変換演算子
を呼び出すか曖昧だからエラーが出たようだ。


69 名前: デフォルトの名無しさん 投稿日: 02/11/23 05:11
そうすると、
return std::auto_ptr<B>(p);は、コピーコンストラクタなのか、それとも
変換演算子なのか?誰か教えてください。


70 名前: デフォルトの名無しさん 投稿日: 02/11/23 05:23
さらに深く調べると、
return std::auto_ptr<B>(p); もエラーになるのは、これもコピーコンストラクタか
変換演算子なのか曖昧だという事がわかった。

エラーを回避するには、
std::auto_ptr<B> f()
{
std::auto_ptr<D> p;
return std::auto_ptr<B>(std::auto_ptr<D>(p));
}

のように書かなければいけないようだ。この場合コンパイル出力をアセンブリ出力
で見てみると、コピーコンストラクタを呼び出した後変換演算子が呼び出されていた。


71 名前: 60 投稿日: 02/11/23 13:29
>>65-70
えらい!

しかし、もーtemplateの話じゃないねぇ。

http://gcc.gnu.org/ml/gcc-help/2001-07/msg00137.html
同じ話ハケーン

http://www.kuzbass.ru/docs/isocpp/decl.html
8.5.14の最後の方の段落で説明されているようだ。


72 名前: デフォルトの名無しさん 投稿日: 02/11/23 15:48
>>71
ちょっと違うかもしれないが、だいたいこれと同じような現象が起こって
いるようです。

class B;

class A {
public:
A() {}
A(B*) {}
A(B&) {}
};
class B {
public:
operator A() { return A(this); }
};

int main()
{
A a;
B b;
a = b;
}


73 名前: デフォルトの名無しさん 投稿日: 02/11/23 15:50
関数も付け加えてみました。スレ違いにてここまで。

class B;

class A {
public:
A() {}
A(B*) {}
A(B&) {}
};
class B {
public:
operator A() { return A(this); }
};

A f(B& b)
{
return b;
}

int main()
{
A a;
B b;
a = b;
f();
}


74 名前: デフォルトの名無しさん 投稿日: 02/11/23 15:53
あっ、f()でなくてf(b)です。


75 名前: 12 投稿日: 02/11/23 18:33
>>70
return std::auto_ptr<B>(p);
これはエラーにならずに通るぞ。
>>69
こういうのは、「変換コンストラクタ」とか言うんじゃないの?
ちなみに、 std::auto_ptr に「コピーコンストラクタ」は無いと言える、よね?


76 名前: デフォルトの名無しさん 投稿日: 02/11/23 21:16
std::vector<std::string> str;
と宣言して
str.push_back(buf); (bufはchar型の文字列)
という感じで値をつめていくと「識別子が '255' 文字に切り捨てられました」
とコンパイラの警告が出ます。char型の文字列をどんどん追加していきたいのですが、
正しい値の代入の仕方があれば教えてください。


77 名前: デフォルトの名無しさん 投稿日: 02/11/23 21:38
>>76
それは文字列が切りつめられたんじゃなくて、
templateを展開した型の実名が長すぎるから切りつめられただけ


78 名前: デフォルトの名無しさん 投稿日: 02/11/23 22:15
>>76
VC++6.0の仕様
あきらめれ


79 名前: デフォルトの名無しさん 投稿日: 02/11/24 00:48
#pragma warning(disable:4503)
#pragma warning(disable:4786)
で黙らせる。


80 名前: デフォルトの名無しさん 投稿日: 02/11/24 01:05
俺ら最強!YO!



81 名前: デフォルトの名無しさん 投稿日: 02/11/24 02:31
>>65-74
おつかれさま。
チョピーリチミを好きになりますた。



82 名前: デフォルトの名無しさん 投稿日: 02/11/24 11:40
auto_ptrは解決したようなので...

何度も出てる質問だと思うけど、boost仕事で使ってる?
オレんところは小さい会社だし、仕事がR&D的だし、
わがままは通るから勝手に使っちゃってるけど。
templateやSTLでさえも使えない会社って多いんでしょ?
(ならC++なんか使うなって感じだけどな。)


83 名前: デフォルトの名無しさん 投稿日: 02/11/24 11:44
ここのスレの人はgcc使ってるの?
環境がwindowsだとmingw?


84 名前: デフォルトの名無しさん 投稿日: 02/11/24 11:47
>>83
ワシはBCB6れす。boost::lambda使いたいよ〜。
cygwin-bccはまだ2.95だよね?


85 名前: デフォルトの名無しさん 投稿日: 02/11/24 12:17
オレは g++ 3.2 を使って開発してから vc++ に移植、ってパターンが
多いかな。もちろん boost のスマートポインタが無いと仕事になりません。
次期vc++は、boost も loki もちゃんと通るらしい(というか、コンパイル済み
オブジェクトが添付されるらしい)ので楽しみ。↓参照。
http://www.zdnet.co.jp/enterprise/0211/11/n20.html


86 名前: デフォルトの名無しさん 投稿日: 02/11/24 12:20
SDKのコンパイラも新しくなるのかな?


87 名前: デフォルトの名無しさん 投稿日: 02/11/24 12:27
51>>
C++のテンプレートそっくりなものをそのまま使えるわけでは無いようですが、これによりJavaの型キャストの問題に悩まされなくなり、instanceof修飾子を使わずに済むようになり、よりオブジェクト指向的なコードがかけるようです。


88 名前: デフォルトの名無しさん 投稿日: 02/11/24 13:15
>>85
g++使って書いたコードって、VCでコンパイル通る?
俺はだめだ。template周りが弱すぎるよ、VCって。
そんなわけでVCはほとんど使えない。辛うじてBCBかな。



89 名前: デフォルトの名無しさん 投稿日: 02/11/24 13:20
>>85
コンパイル済みオブジェクトが添付されるって、
exportがサポートされるってこと?それはすごい!!!


90 名前: デフォルトの名無しさん 投稿日: 02/11/24 13:31
template <int M, int N=1>
class StaticArray{
public:
inline static const double* init(){
(N-1<M)?(StaticArray<M,1>::data[N-1]=double(N-1)):0;
StaticArray<M,N-1>::init();
return StaticArray<M,1>::data;
}
};
template <int M>
class StaticArray<M,1>{
static double data[];
public:
inline static void init(){ StaticArray<M,1>::data[0]=0;}
template <int,int>
friend class StaticArray;
};
template <int M>
double StaticArray<M,1>::data[M];
int main(){
const double* array=StaticArray<20,10>::init();
for(int i=0;i<20;i++) std::cout << " " << array[i];
std::cout << std::endl;
}
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html
でいってたすたちっくに配列の初期化するのってこんなんだろか


91 名前: デフォルトの名無しさん 投稿日: 02/11/24 13:50
>>88
さすがに export は無理じゃろ。
たんにregexとかのライブラリがコンパイル済みで提供される、
ってことだと思う。


92 名前: デフォルトの名無しさん 投稿日: 02/11/24 14:07
>>91
Lambdaが使えるなら、それでもいいかも。


93 名前: デフォルトの名無しさん 投稿日: 02/11/24 14:13
>>91
いや、そうでもないんじゃない?
C# にジェネリクス実装するのなら、結局 C++ の export 相当の機構が必要になる。
MS 内部でどういう開発グループ分けになってるかは知らないけど、
彼らが知識共有していくとしたら…。


94 名前: デフォルトの名無しさん 投稿日: 02/11/24 14:17
>>93
C#じゃなくてVC++でしょ(8.0だっけ?)
標準に98%準拠っていうあれでしょ。

でも今ので90%だって自称してるんだから期待できないけど。


95 名前: 93 投稿日: 02/11/24 14:32
>>94
おわかりですか?
export が VC++ に実装されるって話題です。
C# で同等の技術が必要になるから C++ でもやるんではないか?
という事です。

というか 98% の残りの 2% はいったい何なんだ。


96 名前: デフォルトの名無しさん 投稿日: 02/11/24 14:35
98っていう数字がなんだか微妙だよね(藁


97 名前: デフォルトの名無しさん 投稿日: 02/11/24 14:50
>>93
C#とJavaのGenericsは基底クラスがあるからなぁ。
C++でうまくいくのかなあ。
残り2%がtemplate周りだったらいやだなぁ。
うまくいくならVC8買っちゃうんだけど。


98 名前: デフォルトの名無しさん 投稿日: 02/11/24 15:11
ttp://pc3.2ch.net/test/read.cgi/tech/1033830935/ の322が
何か言ってるんだが、誰か心当たりは?


99 名前: デフォルトの名無しさん 投稿日: 02/11/24 15:12
2ちゃん内に対するリンクを切るのは止めてくれ。


100 名前: デフォルトの名無しさん 投稿日: 02/11/24 15:26
export とベースクラス Object/object がある事って関係ないんじゃ?


101 名前: デフォルトの名無しさん 投稿日: 02/11/24 19:18
>>98
http://www.codeproject.com/interview/stanlippman14nov2001.asp
> Microsoft’s goal is to have a ‘competitively compliant’ compiler -
> meaning it won’t be 100% compliant. There are a couple of features
> of the ANSI/ISO standard (for instance the ‘export’ keyword as
> applied to template classes) that won’t be implemented because
> they are considered by Microsoft to be obscure and, at this stage,
> theoretical.
とか。ただ、exportなんでEDGのですらサポートされてない
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdndeepc/htm/deep04202000.asp
とか言えた時代と違って、すでにexportが使えるコンパイラが
登場してきてるからには、認識も変化しているかもしれないけど。

>>100
C#のGenericsはどうなるのか知らんけどJavaのGenericsは例えば、
「内部では全てObjectへの参照を保持するようなコンテナをオブジェクトコードとして
生成しておいて、それを利用するソース側のコンパイル時に型チェック/自動型変換を
かける」 みたいな方法で実装してるだけだから参考にならん、という面はあると思うが。

C++にも「Object型があって、変数は全てポインタ」みたいな
制限があればtemplateのexportは相当楽になるわけで。


102 名前: デフォルトの名無しさん 投稿日: 02/11/24 20:02
STLのmapについての質問なのですが、
「mapの要素の挿入と削除には対数時間(logN)が必要ですが、
位置を指定して要素を挿入する場合は償却定数時間(ε)しかかりません。」
と本にあったのですが、いまいちよく分かりません。
(1)削除
void erase(iterator i); -> logN ?
void erase(iterator start,iterator end); -> length*logN ?
size_type erase(const key_type &k); -> logN ?
(2)挿入
iterator insert(iterator i,const value_type &val);-> ε ?
template<class InIter>
void insert(InIter start,InIter end ); -> length*logN ?
pair<iterator,bool> insert(const value_type &val);-> logN ?
であってますでしょうか?


103 名前: デフォルトの名無しさん 投稿日: 02/11/25 12:45
>>102
位置指定が正しい場合にのみ、定数時間で挿入ができるらしい。
ttp://www.sgi.com/tech/stl/UniqueSortedAssociativeContainer.html

で、「正しい位置」は lower_bound で取れる。


104 名前: 102 投稿日: 02/11/25 15:09
「反復子で指定した要素の削除は定数時間です。」を忘れてました。
void erase(iterator i); -> ε に修正します。

>>103
[挿入|削除]する[位置|反復子]が分かっているときは定数時間だが、
その位置を探すのにlower_bound ->logN 時間かかるということですかね。
ありがとうございました。





105 名前: デフォルトの名無しさん 投稿日: 02/11/26 19:20
type_of演算子作りたいんだけど。

コンパイラがどの型にも固有の値を割り振っていて、
それをコンパイル時に参照できたら
式templateとマクロでtype_of作れるんだけど、
静的使えるのがsizeofしかないぽいから無理くさいのかな。

//ないんでとりあえず実験
#define class_id(x) sizeof(x)

template <int> struct Type_of;
struct Type_of<class_id(int)>{typedef int type;};
struct Type_of<class_id(char)>{typedef int type;};

#define type_of(x) Type_of<class_id(a)>::type

#include<iostream>
int main()
{
int a;
char c;
type_of(a) a2=200;
type_of(c) c2=100;
std::cout << a2 << c2;
}



106 名前: 105 投稿日: 02/11/26 19:31
修正:
× struct Type_of<class_id(char)>{typedef int type;};
○ struct Type_of<class_id(char)>{typedef char type;};


107 名前: >>105 投稿日: 02/11/26 21:34
VC++7.0 限定でよければ…(C++の規格的には間違っているらしい)
-----------------------------------------------

typedef char (&no_tag)[1], (&yes_tag)[2];
template<int> struct id_counter;
template<typename> struct t2t;
template<typename T> no_tag test(T*, ...);
#define EMPTY(n) sizeof(test((t2t< id_counter<n> >*)0))==sizeof(no_tag)

template<int val_ =
(EMPTY(1) ? 1 :
(EMPTY(2) ? 2 :
(EMPTY(3) ? 3 :
(EMPTY(4) ? 4 :
(EMPTY(5) ? 5 :
(EMPTY(6) ? 6 :
(EMPTY(7) ? 7 :
(EMPTY(8) ? 8 :
(EMPTY(9) ? 9 :
-1)))))))))> struct id_counter {
enum { val = val_ };
friend yes_tag test( t2t< id_counter<val> >* );
};

template<typename T> struct id_of { enum { val = id_counter<>::val }; };
#define class_id(T) id_of< T >::val


108 名前: 107 投稿日: 02/11/26 21:37
#include <iostream>
int main()
{
std::cout << class_id(int) << ' '
 << class_id(int) << ' '
 << class_id(char) << ' '
 << class_id(int) << ' '
 << class_id(long) << ' '
 << class_id(std::istream) << std::endl;
}



1 1 2 1 3 4

になる。とゆーか、分割コンパイルまで考えると、コンパイラ的にはtypeofよりも
staticなTypeIdの方がよっぽど面倒な気がするので、素直にc++0xを待つべきかと。


109 名前: 107 投稿日: 02/11/26 23:02
今思いついた。sizeofと同じく式に対しても使えるようにするには、こんな感じ。

template<typename T> struct sized { char size[id_of<T>::val]; };
template<typename T> sized<T> obj_class_id_helper(const T&);
#define obj_class_id(x) sizeof(obj_class_id_helper(x).size)

//int a; float b;
//assert( obj_class_id(a+b) == class_id(float) );


110 名前: 105 投稿日: 02/11/27 11:30
>>107
すごすぎる!!!
id_counterってほんとにその名の通りですね。
少し手を加えて
type_ofとtestプログラム作ってみたけど、
こういうものはウプしてもいいのかな?(どういう場所がいいのか)
どうにか手を入れれば、GCCでも動かせそうな気がするんだけど、
自分では無理そうでした。



111 名前: デフォルトの名無しさん 投稿日: 02/11/27 14:20
>>107
逆に、IDから元の型を取得することはできないの?

float f = 1f;
int i = (class_id(int))f;

キャストに使えたりするとうれしい。


112 名前: デフォルトの名無しさん 投稿日: 02/11/27 17:34
よく使う foo とか bar とかって、RFC で定義されてたんだな。
知らなかった。
http://www.puni.net/~mimori/rfc/rfc3092.txt


113 名前: デフォルトの名無しさん 投稿日: 02/11/27 18:17
jokeだろ


114 名前: デフォルトの名無しさん 投稿日: 02/11/27 18:35
>113
しっ!!


115 名前: デフォルトの名無しさん 投稿日: 02/11/27 18:47
うお!IPってデータリンク層に鳩使っても使用可能なんだってさ!
RFC勉強になりすぎ。


116 名前: 107 投稿日: 02/11/27 19:27
ネタ元は
http://lists.boost.org/MailArchives/boost/msg37791.php
ね。

>>111
それが出来ると typeof の完成なんだけど、思いつかないっす。
105氏のType_ofみたいに、必要なクラスのid - typeのマッピングを
全部手で書いていくくらいしか。何か上手い手はないかな。


117 名前: 105 投稿日: 02/11/28 08:48
ttp://www3.to/typeof
にとりあえず上げてみました。
中を見ると分かるけど

>>111
int i = (type_of_id( class_id(int) ))f;
でできます。でもType_ofで登録した物にしか使えません。

>>107
ちょこっと追加として
int addfunc(int,int);
type_of_declare(addfunc(int,int),aa);
std::cout << aa;
とかできるようにした。(定義場所わかりにく...

>>107(116)
入れ子の式テンプレートでできないかと思ったけど撃沈...。(以下、略
template <typename T> struct Type_of_collection
{
template <int N> struct Type_of_Num;
struct Type_of_Num<class_id(T)> { typedef T type;};
};


118 名前: デフォルトの名無しさん 投稿日: 02/11/28 12:01
Intel C++ Compiler 7.0 age

ttp://www.xlsoft.com/jp/products/vtune/icppwin.html


119 名前: デフォルトの名無しさん 投稿日: 02/11/28 15:05
質問です。VC++6.0で

#include <list>
using namespace std;
void main(){
list<list<int>> a:
}
というのでエラーがでます。
listのlistを作るにはどのようにしたらいいのでしょうか?



120 名前: デフォルトの名無しさん 投稿日: 02/11/28 15:09
>>が引き篭もりなのです


121 名前: デフォルトの名無しさん 投稿日: 02/11/28 15:10

>list<list<int>> a:
色々違ってるな。




122 名前: デフォルトの名無しさん 投稿日: 02/11/28 15:11
>120

ありがとうございました。
直りました。


123 名前: デフォルトの名無しさん 投稿日: 02/11/28 15:37
>>118
ただなの?


124 名前: デフォルトの名無しさん 投稿日: 02/11/28 16:26
>C++ Compiler 7.0 for Windows \55,000


125 名前: デフォルトの名無しさん 投稿日: 02/11/29 06:09
std::vectorのstd::sortが予想外に速い。インライン展開の賜物か。

const int N = 2000000;
int cmp(const void *, const void *);

int main()
{
static double d[N];
std::vector<double> vd;
std::clock_t ti;

std::srand(0);
for (int i = 0; i < N; i++) d[i] = std::rand();
std::srand(0);
for (int i = 0; i < N; i++) vd.push_back(std::rand());

ti = std::clock();
std::qsort(d, N, sizeof(double), cmp);
std::cout << "qsort = " << std::clock() - ti << std::endl;

ti = std::clock();
std::sort(vd.begin(), vd.end());
std::cout << "sort = " << std::clock() - ti << std::endl;
}


126 名前: デフォルトの名無しさん 投稿日: 02/11/29 06:09
int cmp(const void* a, const void* b)
{
if (*static_cast<const double*>(a) < *static_cast<const double*>(b)) return -1;
else if (*static_cast<const double*>(a) > *static_cast<const double*>(b)) return 1;
return 0;
}

qsort = 906
sort = 734


127 名前: デフォルトの名無しさん 投稿日: 02/11/29 06:11
intだと

qsort = 702
sort = 328

差が開く。


128 名前: デフォルトの名無しさん 投稿日: 02/11/29 06:16
intでcmp()を

int cmp(const void* a, const void* b)
{
return *static_cast<const TYPE*>(a) - *static_cast<const TYPE*>(b);
}

に換えたらちょっと速くできるけどまだsort()の方が速い。よくできてるなあ。

qsort = 562
sort = 344


129 名前: デフォルトの名無しさん 投稿日: 02/11/29 06:24
あっごめん、環境はBorland-C++5.6.2(STLport装備)ね。


130 名前: デフォルトの名無しさん 投稿日: 02/11/29 10:08
Win98SE、VC6SP5、PentiumIII-800。
STL は VC6 付属のもの。
コンパイラ付属のソースをインライン展開しまくった my_qsort でもやってみたよ。

double:
my_qsort = 4340
qsort = 4720
sort = 1760

int:
my_qsort = 1540
qsort = 3240
sort = 830

int (quick cmp):
my_qsort = 1430
qsort = 2520
sort = 830

どうも、インライン展開うんぬんより、アルゴリズムが根本的に違ってるように見える。
STL のソートって何ソートなの?


131 名前:   投稿日: 02/11/29 10:16
sort って比較と入れ替えが処理のメインだから、そこが関数呼び出しになって
しまって最適化されない qsort は正直かなりのオーバーヘッドがあると思う。


132 名前: デフォルトの名無しさん 投稿日: 02/11/29 10:51
>>130
qsort の方はよく知らんが、STL の方は、

基本はクイックソート
pivot には先頭・ど真ん中・末尾の要素の中央値を使う
要素数が小さくなってきたら挿入ソートに切り替える
あと、最新版では再起が深くなってきたらマージソートに切り替えるって機能も付いてたと思われ。



133 名前: デフォルトの名無しさん 投稿日: 02/11/29 11:11
標準のstd::logical_and、std::logical_orの使い方がよくわかりません。
参考書を読むと、標準にはないbinary_composeと組み合わせて使うと
書いてあるのですけど、どういう意味なのでしょうか?


134 名前: デフォルトの名無しさん 投稿日: 02/11/29 11:50
>>131
130 の 3 行目は読んでくれたか?
> int (quick cmp):
> my_qsort = 1430
> sort = 830
その関数呼び出しのオーバーヘッドが無い状態で、これだけ差があるの。

>>132
VC6 付属の qsort.c については、
> pivot には先頭・ど真ん中・末尾の要素の中央値を使う
> 要素数が小さくなってきたら挿入ソートに切り替える
これと同じっぽい
要素数 8 以下で挿入ソートに入る。
ただし、マージソートはやってなくて、再帰は使わずに goto で戻してる。

ネックになりそうなのは、STL の場合のように代入演算子が使えないので、
char 単位にデータ転送しているところかな。
でも、それを無理矢理 int 決め打ちの swap にしても、まだ sort() のが
速い。
> my_qsort = 1100
後は何だ?


135 名前: デフォルトの名無しさん 投稿日: 02/11/29 12:18
>>133
binary_composeにはSGIのSTLやSTLportで定義されている。std::compose2
というヘルパ関数を持つ。

例えば _1 < 1 || 3 <= _1 という関数オブジェクトを作るには

std::compose2(std::logical_or<bool>(), std::bind2nd(std::less<int>, 1), std::bind2nd(std::greater_equal<int>, 3))

とすればよい。

boostではネーミングが異なり、boost::compose_f_gx_hyとなっている。


136 名前: デフォルトの名無しさん 投稿日: 02/11/29 12:24
> ネックになりそうなのは、STL の場合のように代入演算子が使えないので、
> char 単位にデータ転送しているところかな。

double が異様に遅いのはこのせいだな。
インライン展開しまくり、かつ代入演算子に変えたら、sort() に肉薄した。

my_qsort = 1965
qsort = 4715
sort = 1753

でもやっぱり sort() のが遅いけど。


あと、↓でより正確に測れる。

#pragma comment(lib , "winmm.lib")
#define clock_t DWORD
#define clock() timeGetTime()


137 名前: デフォルトの名無しさん 投稿日: 02/11/29 12:24
> でもやっぱり sort() のが遅いけど。

sort() のが速いけど。ですた。


138 名前: デフォルトの名無しさん 投稿日: 02/11/29 12:28
> boostではネーミングが異なり、boost::compose_f_gx_hyとなっている。

スマソ。boost::compose_f_gx_hxとなっている。に訂正します。


139 名前: デフォルトの名無しさん 投稿日: 02/11/29 12:35
>>136
そうだったのか。あらゆる型に汎用にするために、charでアラインされた
転送単位を持つためにqsort()は遅いのか。

ということはcharでsortするとそんなに差は出ないはずだな。

・・・・やってみた。

qsort = 265
sort = 282

測定誤差により、逆転する事もあるが、大ざっぱに測定するとqsort()の
方が速くなった。納得。


140 名前: デフォルトの名無しさん 投稿日: 02/11/29 12:36
STLとboostを一度同じ土俵に上げて、そのよさを比較し、
なし崩しにboostを認めようという作戦ですか?

私は認めませんよ!>boost


141 名前: boost 投稿日: 02/11/29 18:24
>>STL
ごめんなさい



142 名前: デフォルトの名無しさん 投稿日: 02/11/29 19:13
標準 boost → SB


143 名前: デフォルトの名無しさん 投稿日: 02/11/29 19:16
次期STLは間違いなくboostからいくつかの機能を取り入れるだろうに。


144 名前: 小技 投稿日: 02/11/29 22:18
template< class T, class U >
U hoge( T foo, U* = NULL )
{
...
}

// 使い方
hoge<string, int>( "第二引数はダミー" );


145 名前: デフォルトの名無しさん 投稿日: 02/11/30 01:29
>>144
これのどこが技なのか・・・・・


146 名前: デフォルトの名無しさん 投稿日: 02/11/30 01:33
よけーなオーバーヘッド食いそうだ


147 名前: 107 投稿日: 02/11/30 01:45
>>117
> ttp://www3.to/typeof
素晴すぃ。

結局friendで勝手に定義を挿入するしかなさそう、と思ってその方向で
弄ってたんだけど、id_counter と違ってsizeof以上の情報を
オーバーロードされた関数からとってこなきゃいけないのがうまく行かなくて撃沈続き…。


148 名前: デフォルトの名無しさん 投稿日: 02/11/30 09:31
>>144
VC6対策か?


149 名前: デフォルトの名無しさん 投稿日: 02/11/30 11:06
>>145-146
わからんのか?ヒントは返り血


150 名前: デフォルトの名無しさん 投稿日: 02/11/30 11:17
template<class T, class U>
U hoge(T foo, U* up = 0)
{
return *up;
}

int main()
{
hoge<std::string, int>( "第二引数はダミー" );
}

としてみてもなあ。。。。intが無駄に使われているような気がして
ならない。


151 名前: デフォルトの名無しさん 投稿日: 02/11/30 11:21
>150
じゃなくて、ふつーに書くと返り値の型が異なるだけの関数は多重定義できん
という話でしょ。

template じゃなくても良いんだが

int foo();
void foo();

これは NG だが、

int foo(int);
void foo();

これなら行ける。

> intが無駄に使われているような気がして
とりあえず最適化有効にしてアセンブラ出力させてみ。


152 名前: デフォルトの名無しさん 投稿日: 02/11/30 11:22
inline化されたら無駄な引数はなかったことになるだろうねえ


153 名前: デフォルトの名無しさん 投稿日: 02/11/30 11:33
つまり、第二引数の型を変えて多重定義するためというものなのか?
今いち存在意義がわからんが・・・・・・


154 名前: デフォルトの名無しさん 投稿日: 02/11/30 12:13
俺も今一分かってないんだが,

int GetValue("キー")
string GetValue("キー")

みたいなことができるってことかい?


155 名前: 154 投稿日: 02/11/30 12:19
ごめん。なんか違うみたい・・・
具体的な使用例をあげてみてくれないかい?


156 名前: デフォルトの名無しさん 投稿日: 02/11/30 12:52
>>153
templateの特殊化したいときとか使えるけど?

>>155
>>151に書いてあんだろ?アホか?


157 名前: デフォルトの名無しさん 投稿日: 02/11/30 12:58
>>156
155 はそんなことをする理由を訊きたがっているんだぞ。

無理やり使いどころを考えると、template クラスで Factory 関数を使うときか?


158 名前: 154 投稿日: 02/11/30 13:04
>>157
そういうことです
(だから>>154でわざわざ”GetValue"という関数名を使ったのですが伝わらなかったようで・・・)

>無理やり使いどころを考えると、template クラスで Factory 関数を使うときか?
うーん。確かに無理やりですね。

Widget MakeWidget() ※Widgetは基底クラス

ってするもんじゃないでしょうか。

同じ関数名で返り値が違うってのがそもそも想像できないんですが・・・。


159 名前: 154 投稿日: 02/11/30 13:07
連カキすまん。

利用法が無いなら無いでいいんです。
「こういうこともできるよ」って例なのだとしたら。

でも実際に使いどころがあるんでしたら聞いてみたいのです。



160 名前: デフォルトの名無しさん 投稿日: 02/11/30 14:50
>>151
それなら

template<class U, class T>
U hoge( T foo )
{
...
}
// 使い方
hoge<int>( "第二引数なんざ要らん" );

で十分では?古いヘタレコンパイラでどうなるかは知らんが。


161 名前: デフォルトの名無しさん 投稿日: 02/11/30 15:09
>158
> 同じ関数名で返り値が違うってのがそもそも想像できないんですが・・・。
template を使って Mixin (あるいは Strategy パターン) をを書くときに使える。


162 名前: デフォルトの名無しさん 投稿日: 02/11/30 15:12
>160
それだと、明示的に型を指定する必要があるのが難だなぁ。

パラメタとして関数オブジェクト、関数ポインタ、ともかく () つければ処理して
くれるモノ何でも渡せるようにしておくと、コードの汎用性が上がる(場合がある)。


163 名前: 160 投稿日: 02/11/30 16:27
>>162
引数をtemplateにして型指定を緩くしとくと嬉しい、というのはその通りだけど、
この場合関係ないでしょ。(>>144のも同じく明示的な型指定が必要)

違うのは返値の型のみ、という関数を作りたいとき (例えばModern C++ Design の
Factoryパターンの話とか) の話でないの?


164 名前: デフォルトの名無しさん 投稿日: 02/11/30 16:55
>>160
が通るコンパイラが有るなら教えてくれ。



165 名前: デフォルトの名無しさん 投稿日: 02/11/30 17:29
>164
ないだろう。class を typename にすれば通るけど。


166 名前: デフォルトの名無しさん 投稿日: 02/11/30 17:45
class_idだけど、テンプレートの特殊化のときにちょっとだけ違うためだけに
同じもの作らなくて済ませることができそうな気がする。
これって実行時に判定してるのかな?
Tって静的だけどデバッガで見るとswitch文の中は最適化されてないみたいなんです。

template <typename T> struct FFF
{
FFF(T a=0)
{
switch( class_id(T) )
{
case class_id(char):
std::cout << "char" << std::endl;break;
case class_id(short):
std::cout << "short" << std::endl;break;
default:
std::cout << "other" << std::endl;
}
}

};

template <> struct FFF<int>
{
FFF(int a=0)
{
std::cout << "int" << std::endl;
}
};


167 名前: 続き 投稿日: 02/11/30 17:48
int main()
{
//出力結果
FFF<int> fff1; //int
FFF<char> fff2; //char
FFF<short> fff3; //short
}




168 名前: デフォルトの名無しさん 投稿日: 02/11/30 18:59
>>164
VC++.NET と Bcc5.51 と DigitalMarsC++8.31 と
g++3.2 と g++2.95 と Comeau C++4.31 と Intel C++6.0 では通ったが?
通らないコンパイラを教えてくれ。


169 名前: デフォルトの名無しさん 投稿日: 02/11/30 20:21
うっひょっひょ( ゚∀゚ )


170 名前: 続き 投稿日: 02/11/30 21:10
class_id(char) ->1 (enum定数)
class_id(short) ->3 (enum定数)
直接は飛んでないけど、結局同じなんで問題ないか。
(↓最適化なしのものVC)最適化すると変わるんだろうか...。
; 168 : FFF<char> fff2;
mov DWORD PTR -416+[ebp], 1
cmp DWORD PTR -416+[ebp], 1
je SHORT $L23144
cmp DWORD PTR -416+[ebp], 3
je SHORT $L23145
jmp SHORT $L23146


171 名前: デフォルトの名無しさん 投稿日: 02/12/01 00:10
>>153
たとえば >>53



172 名前: デフォルトの名無しさん 投稿日: 02/12/02 12:17
>>21
ひどいことを言うなよ。お前だってアホだったろうが


173 名前: デフォルトの名無しさん 投稿日: 02/12/02 18:17
>>172
ひどいことを言うなよ。


174 名前: デフォルトの名無しさん 投稿日: 02/12/03 20:15
>>168
確か>>164の脳内コンパイルだと通りません。



175 名前: デフォルトの名無しさん 投稿日: 02/12/03 21:23
ネタがないとスレが荒むな。


176 名前: デフォルトの名無しさん 投稿日: 02/12/03 22:35
それもあるけど、昔と比べると荒れすぎ。



177 名前: 164 投稿日: 02/12/03 22:36
>>168,174
悪りィ、TとUが逆転してるのに気付かんかった。
っていうかテンプレ引数の交換は気付きにくいからやめい。


178 名前: デフォルトの名無しさん 投稿日: 02/12/03 23:46
>>177
やめい、って交換しなきゃ第二引数が省略できんだろ。


179 名前: デフォルトの名無しさん 投稿日: 02/12/04 00:29
>>178

template<class T, class U>
T hoge( U foo )
{
...
}

hoge<int>("できますが何か?");


180 名前: 160 投稿日: 02/12/04 00:51
>>177
ああ、なるほど。混乱させてすまなんだ。

U を使うのって Undeducible か何かの略かと思ってたんで>>144
同じに返値U、引数T、になるようにtemplateの方を変えたんだけど、
Tの次はUってことか。自分では2引数以上のtemplateを書くときは
T1、T2、 T3 ... なのでなぁ。


181 名前: デフォルトの名無しさん 投稿日: 02/12/04 00:59
>>179
コロンブス的な発想にチトワラタ(w



182 名前: デフォルトの名無しさん 投稿日: 02/12/04 01:18
素朴な疑問なんだけど
template<class T, class U>

template<typename T, typename U>
とは書かないの?


183 名前: 160 投稿日: 02/12/04 01:27
>>182
個人的には、
・タイプ数減らしたい時はclass。
・template template parameter は class と書くので、
 何となく全部 class で統一したい気分の日は class。
・マジメに書くときはtypename。


184 名前: デフォルトの名無しさん 投稿日: 02/12/04 02:15
漏れは最初に覚えたときにclassのみだったから
テンプレート引数はclassのみ使用。
typenameは
typedef typename T::iterator iterator;
とがぐらいしか使わない。



185 名前: デフォルトの名無しさん 投稿日: 02/12/04 04:03
>>184
漏れはtypenameに直した。
ってか,intとかにも対応するのにclassって気持ち悪いんだよな。C++のintはクラスじゃないし。


186 名前: 184 投稿日: 02/12/04 04:07
>>185
気持ちは分かる。



187 名前: デフォルトの名無しさん 投稿日: 02/12/04 11:59
昨夜、”C++ Templates" をゲット
まだChapter 3までしか読んでないけど、なかなか良さげ


188 名前: デフォルトの名無しさん 投稿日: 02/12/04 13:11
>>187
どこの出版社?(・∀・)イイ?


189 名前: デフォルトの名無しさん 投稿日: 02/12/04 14:02
>>189
Addison-Wesley だが……出たばっかの洋書でふ


190 名前: 189 投稿日: 02/12/04 14:03
× >>189
○ >>188


191 名前: デフォルトの名無しさん 投稿日: 02/12/04 14:13
>>189
ありがd。俺も本屋行って見てくるよ。


192 名前: デフォルトの名無しさん 投稿日: 02/12/04 14:27
>Addison-Wesley だが…
Addison-Wesley キタ─wwヘ√レvv~(゚∀゚)─wwヘ√レvv~─ !!!!
Addison-Wesley、もう大好き♪
分かりやすいし、詳しいし…。



193 名前: デフォルトの名無しさん 投稿日: 02/12/04 19:42
>>183
俺は int などのプリミティブ型も引数に取る場合には typename, クラスしか
引数に取らん場合には class にしてる。まー、趣味の問題だね。


194 名前: デフォルトの名無しさん 投稿日: 02/12/04 19:45
typename と class は全く同一だと聞いた事があるが・・・どこでだっけ?


195 名前: デフォルトの名無しさん 投稿日: 02/12/04 19:48
本屋行ってみたが、洋書は置いてないと言われた。(´・ω・`)ショボーン
日本訳が出るまで最低1年はかかるからなー。


196 名前: デフォルトの名無しさん 投稿日: 02/12/04 20:10
typename自体が無いしょぼーいコンパイラも世の中には存在する。


197 名前: デフォルトの名無しさん 投稿日: 02/12/04 21:02
>196
まだ使ってるのか… 御愁傷様です。


198 名前: デフォルトの名無しさん 投稿日: 02/12/04 22:07
>>194
全く同一だよ。だからみんなして趣味の問題とか個人的にはとか言ってるわけ。

>>195
出たばっかりの洋書はWebで買った方が良いと思う。


199 名前: デフォルトの名無しさん 投稿日: 02/12/05 20:14
VC6sp5にも移植が出来たみたいです
http://fara.cs.uni-potsdam.de/~kaufmann/?page=lokiport


200 名前: デフォルトの名無しさん 投稿日: 02/12/07 16:49
>>199
がいしゅつ
http://pc3.2ch.net/test/read.cgi/tech/1035005882/766


201 名前: デフォルトの名無しさん 投稿日: 02/12/07 18:17
boost::lexical_castで、スペースを含む文字列を変換すると例外が
出ますな。

std::cout << boost::lexical_cast<char*>(std::string("abc def")) << std::endl;
std::cout << boost::lexical_cast<std::string>("abc def") << std::endl;

boost::lexical_castはstd::stringstreamを使って実装しているので、
>>演算子や<<演算子がスペースを区切り文字とみなしてしまう故らしい。
何とかして欲しいですな。


202 名前: デフォルトの名無しさん 投稿日: 02/12/07 18:30
>>201
http://groups.yahoo.com/group/boost/files/lexical_cast_proposition/
…では直ってるので1.30では修正が取り込まれると思いたい。
と言いながら結局1.29には取り込まれなかったけどなぁ。


203 名前: デフォルトの名無しさん 投稿日: 02/12/08 23:26
落ちそうなので一回ageます。


204 名前: デフォルトの名無しさん 投稿日: 02/12/09 00:24
昨日からSTLの勉強をVC++.Netで始めました。
まだ、わかってない部分が多いのですが、質問させてください。

汎用クラスを定義する際、通常のクラス定義のように CSample.h , CSample.cpp
のように宣言と定義を別ファイルにはできないのですか?

ウィザード利用によるクラス定義(一般クラスの作成手順)を行って、
後で、Template <class T> 文を
class CSample
宣言の前につけたり、いろいろしましたが、コンパイルが通りません。
(中間オブジェファイルができません)

結局、定義と宣言を分けないでヘッダファイルのみで全てを記述すれば、OKでした。

実際に汎用クラスを利用する際には、利用箇所によって型決定する事を考えれば
当然のような気もするんですが、そうなんでしょうか?

もしそうなら、複数のファイルで、同一の汎用クラスを利用する際は、利用するファイルに、
定義した汎用クラス全文をインクルードすることになるんでしょうか。


205 名前: デフォルトの名無しさん 投稿日: 02/12/09 00:30
>>204
>複数のファイルで、同一の汎用クラスを利用する際は、
>利用するファイルに、定義した汎用クラス全文を
>インクルードすることになるんでしょうか
そうです


206 名前: デフォルトの名無しさん 投稿日: 02/12/09 00:41
>>204
何度もガイシュツだが、exportキーワードを完全にサポートしている処理系
でなければ、template文の宣言と実体を別のファイルに分けて書くことはできない。

もしexportキーワードが有効であれば、実体部をライブラリにできることになる。


207 名前: 204 投稿日: 02/12/09 00:44
やっぱりそうだったんですね。
しかも、ガイシュツとのことで、もうしわけないです。
ありがとうございました。がんばってみます。


208 名前: デフォルトの名無しさん 投稿日: 02/12/09 01:10
物の本によれば、//1の書き方は正しくなく、//2のように書かなければならないと
いう意見があるのですが、どちらが正しいのでしょうか。
ちなみにコンパイルはどちらでも通ります(gcc3.2)。

struct Test {
template <typename T, typename U>
void func(T x, U y) {
std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl;
}
};

int main()
{
Test t;
t.func(1, 1); // as <int, int>
t.func(1.1, 2.2); // as <double, double>
t.func<int, double>(2, 3.3); //1
t.template func<int, double>(2, 3.3); //2
}


209 名前: デフォルトの名無しさん 投稿日: 02/12/09 01:25
>>208
メンバ関数テンプレートはtと同一のスコープの時は
大丈夫ですが、パラメータとしてtをどこかへ渡すと
t.template と書く必要があります。


210 名前: デフォルトの名無しさん 投稿日: 02/12/09 01:34
>>209
大丈夫なようですが・・・・・意味を勘違いしてるかな?

struct Test {
template <typename T, typename U>
void func(T x, U y) {
std::cout << typeid(x).name() << ' ' << typeid(y).name() << std::endl;
}
};

void abc(Test& t)
{
t.func(1, 1.1);
}

int main()
{
Test t;

abc(t);
}


211 名前: デフォルトの名無しさん 投稿日: 02/12/09 01:41
>>210
あんまり適当なことを言うのもあれなんで識者の人に
聞きたいところだけど、
基本的には型推論できるところは.templateは要らないと思った。
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html
に書いてあったんだけど、900番台がなぜか抜けてるんだよね。。。

これ以上は分りません。すんまそん。


212 名前: デフォルトの名無しさん 投稿日: 02/12/09 01:58
>>210
わざわざすみません。いろいろ実験してみたら、下のエラーとコメントしてある
行で、'<'がどうも比較演算子とコンパイラが勘違いしてエラーになるようです。

こういう場合、template限定子を付けて、後に続く'<'が型名のパラメータの
始まりである事を示さなければならないようです。

まだよくわかってないのですが、さらに実験してみます。

struct Test {
template <typename T, typename U>
T test(U x) {
std::cout << typeid(T).name() << ' ' << typeid(x).name() << std::endl;
return static_cast<T>(x);
}
};

template <typename T>
T abc(T x)
{
Test t;
T y;
// y = t.test<T>(x); // エラー
y = t.template test<T>(x);
return y;
}

int main()
{
abc(1.1);
}


213 名前: デフォルトの名無しさん 投稿日: 02/12/09 01:58
スマソ>>211さんに対してのレスです。


214 名前: デフォルトの名無しさん 投稿日: 02/12/09 08:40
>>212
それはコンパイラのバグだと思う…。

> template <typename T>
> T abc(T x)
> {
> Test t;
> T y;
> y = t.test<T>(x); // エラー

だと t の型はtemplateパラメータ T に依存せずに決定しているので、
わざわざ template 限定子を入れる必要はないはず。t の型が T に
依存するなら、test がメンバ関数 template であることはパース時には
わからんから、明示的な template 限定子が必要になるけれど。

例えばもし
> template <typename Y>
> struct Test {

> T abc(T x)
> {
> Test<T> t;
だったら、tの型がTに依存するので、必要。


215 名前: デフォルトの名無しさん 投稿日: 02/12/09 13:29
漢字のテクスチャを管理するデータ構造を作りたいです。
機能と優先順位は
1.内部で管理しているテクスチャのハンドル数が最大数を超えたら最も古いハンドルを開放する。
2.sjisのコードを指定するとデータ構造からテクスチャのハンドルを検索して返す。
3.ハンドルが存在しなければその時点でテクスチャを生成してそのハンドルを返す。
で、要素の構造体はこんな感じです。
struct{
unsigned short Code; /// 文字コード
void *Handle; /// テクスチャハンドル
};

要するにキャッシュの機構なんですがとりあえず
hashでインスタンスを、queueで参照を管理するというのを
思いついたんですが他に効率的な方法はありますか?



216 名前: bloom 投稿日: 02/12/09 13:40

http://www.agemasukudasai.com/bloom/


217 名前: デフォルトの名無しさん 投稿日: 02/12/09 15:33
>>214
いろいろやってみたけど、templateパラメータは現れた順に解決される
みたいですね。

コンパイラはgcc3.2(MinGW)を使ってみたんですけど、やっぱりバグです
かね。プログラミング言語C++第3版§C.13.6、P971を読んでいたら、メンバ
テンプレートの型の推定が不可能な場合、メンバ関数名の次に現れる
"<"を比較演算子と見なしてしまいコンパイルエラーになるような事が
書いてありました。

でもそのような事はまれなので、エラーが生じた場合のみtemplate限定子
を付けるようにしようと思います。


218 名前: デフォルトの名無しさん 投稿日: 02/12/09 21:47
>>204
オソレスだが、次のようにするとVC7でも分割できる。

--- T.h ---
template <typename T>
void print(const T&);

--- T.cpp ---
#include <iostream>
#include "T.h"

template <typename T>
void print(const T& t)
{    std::cout << t << std::endl; }

template void print<int>(const int&);

--- main.cpp ---
#include "T.h"

int main()
{
   int i = 10;
   print(i);

   return 0;
}


219 名前: デフォルトの名無しさん 投稿日: 02/12/09 22:20
> template void print<int>(const int&);

template にする意味あんまりないじゃん。


220 名前: 204 投稿日: 02/12/09 22:40
>218
ありがとうございます。動きました。

この場合、T.cpp をコンパイルする際には、実際の利用時の型を T.cpp 内部で明確にし、
それぞれの型別動作をオブジェファイルに記述している。と考えていいんですよね。

main 部に { double d ; print d } を追加するとリンクできないが、
T.cpp に template void print<double>(const double&); を記述すると正常動作したので、
このように解釈しました。


221 名前: デフォルトの名無しさん 投稿日: 02/12/09 22:53
>>219
たしかに、語源的な意味しか残ってないわな。

>>220
おおむね合ってます。「明示的なインスタンス化」っていうやつですわ。


222 名前: デフォルトの名無しさん 投稿日: 02/12/10 00:28
ソースファイル

プレコンパイル

ソース内包オブジェクトファイル

リンク

ソース内包リンクドモジュール

ポストコンパイル

ロードモジュール

という方式にすれば、export 対応はそんなに難しくないと思うんだけど・・・。


223 名前: デフォルトの名無しさん 投稿日: 02/12/10 19:15
>222
簡単に逆コンパイルできちゃうような代物だと、そもそも export 使う意味が無いと
思うんだが。速度の話なら pre compiled header って手もあるわけだし。


224 名前: デフォルトの名無しさん 投稿日: 02/12/10 19:22
export って逆コンパイルと何か関係あるの?


225 名前: デフォルトの名無しさん 投稿日: 02/12/10 21:38


でさ、、、、

どれが一番速いの?


226 名前: デフォルトの名無しさん 投稿日: 02/12/10 21:39
何の話?


227 名前: デフォルトの名無しさん 投稿日: 02/12/10 21:48
どのライブラリが一番効率よいかってこと。




228 名前: デフォルトの名無しさん 投稿日: 02/12/10 21:49
STLport 4.5.3をVC6sp5で使おうと思ってインストールしたんですが、
BoundsCheckerがSTLportのアロケータ(たぶん)みたいなところで
メモリリークを検出してくれます。

#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
  std::string hello = "Hello, world!";
  std::cout << hello << std::endl;
  return 0;
}
こんなコードでも1600バイトのリークが検出されます。
_STLP_USE_NEWALLOCマクロを使えば出なくなるんですが、遅くなりそうだなー
ってのと、Configuration Manualに

When using tools like Purify (c), Codeguard (c) or BoundsChecker (c),
it is advised to #define _STLP_USE_MALLOC or _STLP_USE_NEWALLOC,
otherwise pointer checking will generally not be available on most STL
internal structures, thus defeating the purpose of those tools.

とあるので気にしなくていいってことなんでしょうか?


229 名前: デフォルトの名無しさん 投稿日: 02/12/10 22:10
>228
気にするな。


230 名前: デフォルトの名無しさん 投稿日: 02/12/11 02:14
>>228

実際STLportのdefault allocatorは一度確保したら絶対返さない。

> とあるので気にしなくていいってことなんでしょうか?

時と場合で気にしたりしなかったり

allocatorつかったらmallocされっぱなしでも困らないならそのまま

返してくれなきゃ困る場合はSTLP_USE_MALLOCとか
自前でallocator用意すれ


231 名前: デフォルトの名無しさん 投稿日: 02/12/11 18:56
Effective STLなかなか良さげ


232 名前: 学習能力の無い人 投稿日: 02/12/12 13:06
mapにconst reference operator[]() constって
何で無いの?
毎回const map作って[]使おうとすると怒られるから
constはずすってことをつい繰り返しちゃうんだけど・・・。


233 名前: デフォルトの名無しさん 投稿日: 02/12/12 14:00
>>232
std::mapの[]演算子は、対応するキーがないと、自動的に挿入する仕様になって
いるから。その時点で既にconstでは無い。

[]が便利な事は認めるが、できるだけfindとinsertを使おう。例えばstd::multimapには
[]演算子が無い。仕様をよく考えると当然だが、最初この事を知ったとき、STLには
設計ミスがあるのではないかと思ってしまった。


234 名前: デフォルトの名無しさん 投稿日: 02/12/13 02:10
対応するキーがないと自動的に挿入する、という機能が欲しい時に [] を使わない
理由があるの?


235 名前: デフォルトの名無しさん 投稿日: 02/12/13 09:32
>234
効率。


236 名前: デフォルトの名無しさん 投稿日: 02/12/13 11:04
>>235
コード量が増える割には、見合った効果が得られないけど?

初期要素 500,000、試行回数 5,000,000 で試してみた。
挿入が全く発生しない状況でも、1 % 程しか遅くならない。
挿入しか発生しない場合は 5 % 程遅い。

それとも、漏れの書き方が悪い?

int r = large_rand();
map<int, int>::iterator itr = m2.find(r);
if(itr == m2.end())
itr = m2.insert(pair<int, int>(r, 0)).first;
return itr->second;


237 名前: デフォルトの名無しさん 投稿日: 02/12/13 11:16
つーか、233 の 「例えば」 の前後が繋がってないよ。


238 名前: デフォルトの名無しさん 投稿日: 02/12/13 17:37
236のコードを見て気が付いたが、
find,insertではコピーコンストラクタが呼ばれて
[]演算子だとデフォルトコンストラクタが呼ばれた後に
=演算子が呼び出されるんだな。

だからintではなくもっと複雑な型じゃないと差は出ないのかも。

逆に、find,insertでは二回検索するので余計に遅くなりそうな気がするのだが
236の結果を見るとそうでもないのが不思議。


239 名前: 237 投稿日: 02/12/13 18:00
>>238
> find,insertでは二回検索するので余計に遅くなりそうな気がするのだが

漏れも最初そう思ったけど、find が意外に速いんだよね。
ちなみに、[] の実装はこうだったよ。

_Tref operator[](const key_type& _Kv)
{
 iterator _P = insert(value_type(_Kv, _Ty())).first;
 return ((*_P).second);
}

つまり、236 のコードの、if より下と全く同等。
だから、テストでは find のミスヒット分だけ遅くなったという事だね。

> find,insertではコピーコンストラクタが呼ばれて
> []演算子だとデフォルトコンストラクタが呼ばれた後に
> =演算子が呼び出されるんだな。

上に示した通り共通の動作をしているので、これは違うと思う。


240 名前: 238 投稿日: 02/12/13 20:30
スマソ、勘違いしてた。
何を思ったか[]演算子を使う方に

m2[r]=0;

みたいなコードを想像してた。
これじゃ動作が違うのに。


241 名前: デフォルトの名無しさん 投稿日: 02/12/13 21:05
>>239
そんなタコな実装ねぇだろ。
その実装だと、
・二回検索することになる
・挿入しない場合にも一時オブジェクトの生成・破棄がおこなわれる。


242 名前: 239 投稿日: 02/12/13 21:13
> そんなタコな実装ねぇだろ。

VC6 に付属の STL をそのままかっぱらってきたんだが・・・。
ところで、どこが 2 重検索になるって?


243 名前: 241 投稿日: 02/12/13 22:42
ほんとだ>VC6
おそろしい。

あ、二回検索にはならねぇな。
236と脳内ブレンドされてたよ。スマソ


244 名前: デフォルトの名無しさん 投稿日: 02/12/13 22:55
* Copyright (c) 1994
* Hewlett-Packard Company
だと、
Allocator<T>::reference operator[](const key_type& k) {
 return (*((insert(value_type(k, T()))).first)).second;
}
だな。
まぁ、なんだ。たしかに簡潔といえば簡潔だが……


245 名前: デフォルトの名無しさん 投稿日: 02/12/14 01:00
std::mapのoperator[]は特異な存在だけど、便利であるがゆえによく使う。


246 名前: デフォルトの名無しさん 投稿日: 02/12/14 01:03
コードがかさばってでも速い方がいいというなら、C++ を使う理由はない。


247 名前: デフォルトの名無しさん 投稿日: 02/12/14 01:09
STLportのstd::bit_vectorと、Boostのboost::dynamic_bitsetの使い分けは
どのようにされていますか?


248 名前: デフォルトの名無しさん 投稿日: 02/12/14 03:08
コードがかさばっても速さと汎用性が両立できるなら、C++を使う理由になる。


249 名前: デフォルトの名無しさん 投稿日: 02/12/14 04:38
> 汎用性

何の話?


250 名前: デフォルトの名無しさん 投稿日: 02/12/14 10:45
>249
スレの趣旨から言って Generic プログラミングだろう(違うか)


251 名前: デフォルトの名無しさん 投稿日: 02/12/15 23:10
vc++ver7.0でもtupleは使えない。ok?


252 名前: デフォルトの名無しさん 投稿日: 02/12/16 00:45
#include<string>
using namespace std;

template <typename T> struct dd :public T
{
typename typedef dd<T>::value_type char_type;
inline friend operator<(const dd<T>& a1,const dd<T>& a2 ); //(1)
inline friend operator<(const dd<T>& a1,const char_type* a2 );//(2)
dd(){}
~dd(){}
dd(const char_type* a){ *this=a;}
};

template <typename T> bool operator<(const dd<T>& a1,const dd<T>& a2 )
{
return ((const T&)a1 < (const T&)a2);
}

template <typename T> bool operator<(const dd<T>& a1, const dd<T>::char_type* a2 )
{
return ((const T&)a1 < a2);
}

int main()
{
dd<string> D("abc"),D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) NG
}
templateのoperatorで
(2)のような場合、実装をクラスの中に書くしかないのでしょうか?


253 名前: デフォルトの名無しさん 投稿日: 02/12/16 01:04
修正:
dd(const char_type* a)
{
static_cast<T&>(*this)=a;
}
ですね。
追記:
friendなんだからクラス内に実装を書けということなのか、
friendの行を削除したらOKでした。


254 名前: デフォルトの名無しさん 投稿日: 02/12/16 01:30
テンプレートクラスはfriendをメンバに取ることはできないね。


255 名前: デフォルトの名無しさん 投稿日: 02/12/16 01:36
しまった、テンプレートクラスもfriendはメンバに取れるね。逝ってくる・・・


256 名前: デフォルトの名無しさん 投稿日: 02/12/16 01:54
>>252>>253
うまくいったよ。ddのコンストラクタはexplicit宣言しておかないと、(1)や(2)で
勝手にstd::operator< が選ばれて警告が出る。

template <typename T>
struct dd : public T {
typedef T value_type;
typedef typename dd<T>::value_type char_type;
friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1)
friend bool operator< <T>(const dd<T>& a1, const char_type* a2);//(2)
dd() {}
explicit dd(const char* a){
static_cast<T&>(*this) = a;
}
~dd() {}
};


257 名前: デフォルトの名無しさん 投稿日: 02/12/16 01:55
template <typename T>
inline bool operator<(const dd<T>& a1,const dd<T>& a2)
{
return ((const T&)a1 < (const T&)a2);
}

template <typename T>
inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2)
{
return ((const T&)a1 < a2);
}

int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK
}

friend宣言で未解決のテンプレートパラメータがあると、非テンプレート関数として
コンパイルされてしまうらしいから、型特定して警告を回避した。


258 名前: デフォルトの名無しさん 投稿日: 02/12/16 02:12
でもまだおかしいや。(2)が実行されてないようです。

template <typename T>
struct dd : public T {
typedef T value_type;
typedef typename dd<T>::value_type char_type;
friend bool operator< <T>(const dd<T>& a1, const dd<T>& a2); //(1)
friend bool operator< <T>(const dd<T>& a1, const typename dd<T>::char_type* a2);//(2)
dd() {}
explicit dd(const char* a){
static_cast<T&>(*this) = a;
}
~dd() {}
};


259 名前: デフォルトの名無しさん 投稿日: 02/12/16 02:13
template <typename T>
inline bool operator<(const dd<T>& a1,const dd<T>& a2)
{
std::cout << "dd<T> < dd<T>" << std::endl;
return ((const T&)a1 < (const T&)a2);
}

template <typename T>
inline bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2)
{
std::cout << "dd<T> < dd<T>::char_type" << std::endl;
return ((const T&)a1 < a2);
}

int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK、しかし実行されない?
}


260 名前: デフォルトの名無しさん 投稿日: 02/12/16 05:05
>>259
基底クラス(std::string)の operator<(const std::string&, const char*) が
呼ばれているようだな
通常の関数とテンプレート関数が多重定義されている場合、通常の関数が
優先されるからな


261 名前: デフォルトの名無しさん 投稿日: 02/12/16 09:57
継承したクラスのオブジェクトは自分自身を指すのだね。
template <typename T> struct dd :public T
{
typedef typename dd<T>::value_type char_type;
friend bool operator<(const char_type* a1, const dd<T>& a2 )
{
cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!!
return (a1 < (const T&)a2);
}
dd(){m_str="2ch";}
~dd(){}
explicit dd(const char_type* a)
{
dd::dd();
static_cast<T&>(*this)=a;//なんとm_strにaが入る
}
private:
string m_str;
};



262 名前: 続き 投稿日: 02/12/16 09:57
template <typename T> bool operator<(const dd<T>& a1,const dd<T>& a2 )
{
cout << "(1)" << endl;
return ((const T&)a1 < (const T&)a2);
}
template <typename T> bool operator<(const dd<T>& a1, const typename dd<T>::char_type* a2 )
{
cout << "(2)" << endl;
return ((const T&)a1 < a2);
}
int main()
{
dd<string> D("abc"),D2("efg");
D < D2; //(1) OK
D < "abc"; //(2) OK
"abc" < D; //(3) OK
}


263 名前: デフォルトの名無しさん 投稿日: 02/12/16 11:21
>>261
>cout << "(3) m_str ->"<< a2.m_str << endl;//何も表示されない!!
m_str は初期化時の空文のままだから、表示されないのは当たり前。
>static_cast<T&>(*this)=a;//なんとm_strにaが入る
そんなわけね〜だろ!

なんか、バカでっかい勘違いしてんぞ




264 名前: 引き篭もり 投稿日: 02/12/16 12:48
レベルたけぇ・・・(-_-)


265 名前: デフォルトの名無しさん 投稿日: 02/12/16 13:20
int main()
{
dd<std::string> D("abc"), D2("efg");
D < D2; //(1) OK
D < std::string("abc";) //(2) OK
}

のように、sts::stringの一時変数を作って渡してやらないと、テンプレート関数
の方を呼んでくれない。この当たりがテンプレートの限界なのか。


266 名前: デフォルトの名無しさん 投稿日: 02/12/16 13:26
しかし、ちょっと疑問なのだが、

explicit dd(const typename dd<T>::char_type& a){
static_cast<T&>(*this) = a;
}

これって一体どこに代入しているの?どうみても自分自身に代入しているように
しか見えないのだが・・・・・どんな意味があるのだろう。


267 名前: デフォルトの名無しさん 投稿日: 02/12/16 13:59
基本的な質問です。
More Effective C++のp.16、l2に実際のプログラムでは、このようなクラスはテンプレートになるのだが、
とあります。具体的にはどのように書けばいいのでしょうか?



268 名前: デフォルトの名無しさん 投稿日: 02/12/16 14:06
>>266
なんか激しく気持ち悪い書き方だなぁ。
*(static_cast<T*>(this)) = a;
あるいはすなおに
T::operator=(a);
と書いたほうがわかりやすくないかい?


269 名前: デフォルトの名無しさん 投稿日: 02/12/16 14:11
>>267
たんに、要素の型を int きめうちじゃなくてテンプレート引数で
指定できるようにすべきだ、ってことじゃないの?


270 名前: デフォルトの名無しさん 投稿日: 02/12/16 14:14
>>268
というか、素直にこうだろ〜
explicit dd(const typename dd<T>::char_type& a) : T(a) { }



271 名前: デフォルトの名無しさん 投稿日: 02/12/16 14:20
266です。
>>268>>270 やっはりそうですよね。分かりやすく書くことを心がけるようにします。


272 名前: デフォルトの名無しさん 投稿日: 02/12/16 15:33
dd::dd();//このあとすぐにdd::~dd()が呼ばれてるみたい。
static_cast<T&>(*this)=a;//だからm_strは空白になってる。
なんかすごい勘違いしてたな。絶対変だと薄々思ってたけど...

コンストラクタからコンストラクタを呼ぶと直後にデストラクタが呼び出されるのか。

struct A :public string
{
string m_str;
A()
{
m_str="2ch";
cout << "A::A()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
}
A(const char* c) :string(c)
{
A::A();
cout << "A::A(const char*)"<< endl;
}
};

int main()
{
A a("stu");
}





273 名前: デフォルトの名無しさん 投稿日: 02/12/16 15:55
>>272
ちょっと違う。A::A(); と書くと、コンストラクタを呼び出したことにはならない。
単にAの一時変数が作成されてすぐに破棄されるだけ。

明示的にコンストラクタを呼び出すには、コンストラクタ初期化子を使う
しかない。


274 名前: デフォルトの名無しさん 投稿日: 02/12/16 17:27
>A(const char* c) :string(c)
これ、: m_str(c) の間違いではなくて?
こういう書き方あるの?


275 名前: デフォルトの名無しさん 投稿日: 02/12/16 18:12
>>273
なるほど!

>>274
A は stringを継承して、メンバも持っているから...。

A(const char* c) :string(c),m_str("m_str")
{
cout << static_cast<string>(*this) << endl;//stu
cout << m_str << endl;//m_str
}


276 名前: デフォルトの名無しさん 投稿日: 02/12/16 18:22
明示的に呼ぶ場合、
this->A::A();
これならOKなのでは?



277 名前: デフォルトの名無しさん 投稿日: 02/12/16 18:32
>>276
エラーっしょ。


278 名前: デフォルトの名無しさん 投稿日: 02/12/16 18:36
>>277
できるよ。


#include <iostream>

using namespace std;

struct clsA
{
clsA(){cout<<"clsA():"<<hex<<(unsigned int)this<<endl;}
clsA(int){cout<<"clsA(int):"<<hex<<(unsigned int)this<<endl;
cout<<"CASE:clsA::clsA()"<<endl;clsA::clsA();
cout<<"CASE:this->clsA::clsA()"<<endl;this->clsA::clsA();}
};

void main(void)
{
clsA a(int());
}



279 名前: デフォルトの名無しさん 投稿日: 02/12/16 18:42
>>278
コンパイラは何を使った?Borland-C++5.6.2及びgcc3.2(MinGW)は
エラーが出て通らないけど。


280 名前: 278 投稿日: 02/12/16 18:45
>>279
そうなの?
VC5(苦笑)でつ。
M$オンリーの機能なのか?
エラーはどんなの?



281 名前: デフォルトの名無しさん 投稿日: 02/12/16 18:47
>>280
BCC5.6.2の場合。
エラー E2316 constructor2.cpp 12: 'clsA' は 'clsA' のメンバーではない(関数 clsA::clsA(int) )

gcc3.2(MinGW)の場合。
C:/MinGW/Learn/constructor2.cpp: In constructor `clsA::clsA(int)':
C:/MinGW/Learn/constructor2.cpp:12: parse error before `;' token

というエラーです。


282 名前: 278 投稿日: 02/12/16 18:50
>>281
わざわざTHXです。
…う〜ん。いよいよM$の仕様のような気が。
参考書引っ張り出してもう一度調べてみマフ...



283 名前: デフォルトの名無しさん 投稿日: 02/12/16 18:51
>>282
俺も調べてみるが、確かコンストラクタからコンストラクタを呼び出すには、
初期化リストしか方法がなかったように記憶しているが・・・・どうだったっけな


284 名前: デフォルトの名無しさん 投稿日: 02/12/16 19:50
>>282
どっかのメーリングリストではVC固有の機能だと言われてたな。

>>283
ちょっと話は変わるけど、こんなのどう?

static_cast<T*>(this)->~T();
new(this)T(param);

newで例外が起きるとヤバイが。


285 名前: デフォルトの名無しさん 投稿日: 02/12/16 19:53
>>284
newの配置構文ですね。この場合、デストラクタは自分で呼び出してやらないと
いけないですね。


286 名前: デフォルトの名無しさん 投稿日: 02/12/16 20:57
>>285
だから直前に呼んでるみたいだが


287 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:04
>>285
そうか? 
この場合、Tは(*this) の型の基底クラスだろ
この型のデストラクタがデフォで ~T() 呼ぶから
大丈夫だと思うんだが、どうよ

>>286
ちょっと、目の付け所がいまいち


288 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:08
>>287
そっか。そう言われればそうだな。途中でリコンストラクトした事にはコンパイラ
は気づいてないだろうからね。


289 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:18
>>269 ありがd



290 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:25
>>284
× new(this)T(param);
○ new (static_cast<T*>(this)) T(param);


291 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:33
// こんな感じ?
#include <iostream>
using namespace std;

struct Base {
 Base() {
  cout << "Base::Base()" << endl;
 }
 virtual ~Base() {
  cout << "Base::~Base()" << endl;
 }
};

struct Ero : public Base {
 Ero() {
  cout << "エロ::エロ()" << endl;
 }
 ~Ero() {
  cout << "エロ::~エロ()" << endl;
 }
 Ero(int) {
  Base::~Base();
  new(this) Ero();
  cout << "エロ::エロ(int)" << endl;
 }
};

void main() {
 Ero ero(0); // エロ(0)
}


292 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:46
>>291
実行結果が次のようになったのだが、大丈夫だろうか?

Base::Base()
エロ::~エロ() //←これヤバくない?
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()


293 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:49
>>291
// ぜんぜん違うぞ、こうだ
#include <iostream>
class Foo
{
   int m;
public:
   Foo(int n = 0) : m(n)
   {   std::cout << "Foo is created by " << n << std::endl; }
   int val() const { return m; }
   ~Foo()
   {   std::cout << "Foo is destroyed. m = " << m << std::endl; }
};

template <typename T> class Bar : public T
{
public:
   Bar (int n = 0)
   {
       std::cout << "Bar is created by " << n << std::endl;
       static_cast<T*>(this)->~T();
       new (static_cast<T*>(this)) T(n);
   }
   ~Bar()
   {   std::cout << "Bar is destroyed." << std::endl; }
};

int main()
{
   Bar<Foo>(10);
}


294 名前: 293 投稿日: 02/12/16 21:55
今気づいたが、
テンプレート使う必然性無く、まったくレス違いなネタのような……


295 名前: デフォルトの名無しさん 投稿日: 02/12/16 21:59
>>293
ををををぉぉぉぉなんとトリッキーな。

Fooのインスタンスが先に生成されるのが意外だったけど、これは使えそうだね。


296 名前: 291 投稿日: 02/12/16 22:03
>>292
やばいです。
つーか、うち(VC7)ではこうなりました。
仮想関数テーブルの取り出し方が違うのでしょうか?

Base::Base()
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)
エロ::~エロ()
Base::~Base()

>>293
飛び入りな者でスミマセン。


297 名前: デフォルトの名無しさん 投稿日: 02/12/16 22:20
>>296
>>292はBorland-C++5.6.2です。
gcc3.2(MinGW)でやったら、次のようなエラーが出てコンパイルできませんでした。

C:/MinGW/Learn/constructor3.cpp: In constructor `Ero::Ero(int)':
C:/MinGW/Learn/constructor3.cpp:20: cannot call destructor `Base::~Base'
without object


298 名前: デフォルトの名無しさん 投稿日: 02/12/16 22:24
gcc3.2(MinGW)は次のようにしたらコンパイルできて、実行結果は以下の通りです。

Ero(int) {
this->Base::~Base(); // thisから呼び出すようにした
new(this) Ero();
std::cout << "エロ::エロ(int)" << std::endl;
}

Base::Base()
Base::~Base()
Base::Base()
エロ::エロ()
エロ::エロ(int)

コンパイラによって実行結果がバラバラですね(^_^;)。


299 名前: デフォルトの名無しさん 投稿日: 02/12/16 22:36
昨日から Modern C++ Design 読み始めたがなんだか
出じゃブーが多いなあ。


300 名前: デフォルトの名無しさん 投稿日: 02/12/16 22:54
Phoenix Singleton とかな(藁


301 名前: デフォルトの名無しさん 投稿日: 02/12/16 23:01
>>298
>コンパイラによって実行結果がバラバラですね(^_^;)。
データレイアウトの違いが原因かも(根拠なし)


302 名前: デフォルトの名無しさん 投稿日: 02/12/16 23:44
>>300
300getしてるよ。
2〜3年前に似たようなこと頑張って考えてた時期あった。
基本型とユザ定義型の区別とか。
コンパイル時のじゃなくて実行時に区別するやつ。
ただしおれは目的があくまでパズルだった。
実用にしようと思ってたらなんか結果出てたかな...?



303 名前: デフォルトの名無しさん 投稿日: 02/12/18 12:04
これって、メモリリークしちゃうの?
しないですよね?
void foo() {
    std::vector<std::string> v;
    v.push_back( *(new std::string("お兄ちゃん♥") );
}


304 名前: デフォルトの名無しさん 投稿日: 02/12/18 12:10
Clear()
{
  for(std::vector<std::string>::iterator it=v.begin(); it!=v.end, ++it)
    delete &(*it);
  v.clear();
}

とかやらないと駄目なんじゃない?


305 名前: デフォルトの名無しさん 投稿日: 02/12/18 12:37
>>304
(*it)はnewで作成したstringを
コピーコンストラクタでコピーした物だからダメだと思うが。


306 名前: 303 投稿日: 02/12/18 12:48
>>304-305
えっと、つまり、
void foo() {
string* p;
std::vector<std::string> v;
v.push_back( *(p = new std::string("美幸...おまえ...") );
delete p;
}
ってやらなきゃだめ、ってことですか?


307 名前: デフォルトの名無しさん 投稿日: 02/12/18 13:07
>>306
そのコードだと、↓といっしょだな。
void foo() {
std::vector<std::string> v;
v.push_back( "美幸...おまえ..." );
}



308 名前: 303 投稿日: 02/12/19 09:26
うん、えっと、std::vectorが、
「なにを保持してるのか、どう扱えばいいのか」を知りたかっただけなのです。
そか、307見たいに書けるって事は、
「std::vector::push_backは、引数を基にして、
変換コンストラクタかコピーコンストラクタで新しいインスタンスを作って、
そのインスタンスを保持する」
ってことだよね。

新しいインスタンスを保持するんだから、
元のインスタンスは自分で解放する必要がある、と。

やっと心のもやもやが。ありがとうでした。


309 名前: デフォルトの名無しさん 投稿日: 02/12/19 09:48
「TIME」誌2002年の顔にアラファト議長を! 3
http://live.2ch.net/test/read.cgi/festival/1040234682/

急募!投票ツール作れる方
97式アラファトマシンガンが無効に!  
アラファトの票がリセット!


310 名前: デフォルトの名無しさん 投稿日: 02/12/19 12:49
次のコードがコンパイルできないんですけどなぜ?

#include <iostream>
template <class T>
struct Hoge
{
    friend void func()
    {   std::cout << "フレンド関数なんだけど" <<std::endl; }
};

int main()
{
    func();
}

VC7では、「error: C2065: 'func': 定義されていない識別子です」とおこられます。
#定義してあんだけどなあ〜


311 名前: デフォルトの名無しさん 投稿日: 02/12/19 12:59
>>310
'func' なんてどこにも定義してないだろ。


312 名前: デフォルトの名無しさん 投稿日: 02/12/19 13:16
しかし、310 の friend void func() は、どうやって呼べばいいんだ?


313 名前: 310 投稿日: 02/12/19 13:36
>>311 >>312
func() はフレンド関数だから、グローバルスコープのはずですけど


314 名前: デフォルトの名無しさん 投稿日: 02/12/19 13:40
template <class T> って書いてある奴の何がグローバルスコープなんだ?


315 名前: デフォルトの名無しさん 投稿日: 02/12/19 13:41
template Hoge<int>;
int main()
{
func();
}
かな。ま、func() が何かHoge型の引数をとってくれないと無意味だわな。


316 名前: デフォルトの名無しさん 投稿日: 02/12/19 13:44
ということで310はtemplateのインスタンス化について小一時間勉強すること。


317 名前: デフォルトの名無しさん 投稿日: 02/12/19 13:48
#include <iostream>
template <class T>
struct Hoge
{
friend void func<T>()
};

template<class T> void func()
{ std::cout << "フレンド関数なんだけど" <<std::endl; }

こうするはず


318 名前: 310 投稿日: 02/12/19 13:57
>>314
template <class T> はHoge に付いているんで、メンバじゃない func() には関係ないと思うけど。

>>315>>316
動きました。でもなぜ?
func() は普通の関数じゃないの? テンプレートじゃない普通の関数をインスタンス化?


319 名前: デフォルトの名無しさん 投稿日: 02/12/19 13:58
> テンプレートじゃない普通の関数

どうしてそう思うのか訊きたいのだが


320 名前: 316 投稿日: 02/12/19 14:03
だから規格書嫁って。
14.5.3
-5- When a function is defined in a friend function declaration in a class template, the function is defined at each instantiation of the class template.


321 名前: 310 投稿日: 02/12/19 14:16
>>319
フレンド関数が func() が テンプレート Hoge のメンバじゃない、っていうのは正しいですよね。
Hoge のtemplate <class T> は、クラスそのものとメンバに対してしか影響せず、パラメータに依存しているわけでもない func() とはまったく関係ないはず。
func() 自体も関数テンプレートとして定義されているわけじゃない。

だから普通の関数だと思うんだけど。


322 名前: 310 投稿日: 02/12/19 14:22
>> 316
へえ、普通の関数でも、個別にインスタンス化されるんだ。
勉強になりました。
でも、ということは、インスタンス化されるごとに同じ定義が再生産されることになるの?
それってやぱくない? 
って、VC7はHoge を複数インスタンス化してもエラーになんないな。大丈夫なのかな?


323 名前: デフォルトの名無しさん 投稿日: 02/12/19 14:35
そのネタくさい物言いなんとかしてください。それにこれは
どっちかというと相談室の方でやる質問なのでは?


324 名前: 310 投稿日: 02/12/19 14:47
>>323
>そのネタくさい物言いなんとかしてください。
それは正直、すまんかった。きおつけるよ
>それにこれはどっちかというと相談室の方でやる質問なのでは?
template がらみだから、こっちに投げたけど、こんどからはそうするよ。



325 名前: デフォルトの名無しさん 投稿日: 02/12/19 15:11
タイトルは s/template/generics/ のほうがよかったかもね


326 名前: デフォルトの名無しさん 投稿日: 02/12/20 00:16
関数テンプレートの関数のアドレスって取ることができないの?

template <typename T>
class Hoge {
T i;
public:
Hoge(T t) : i(t) {}
friend void func<>(Hoge<T>&);
};

template <typename T>
void func(Hoge<T>& t)
{
std::cout << "フレンド関数なんだけど" << std::endl;
std::cout << t.i << std::endl;
std::cout << reinterpret_cast<long>(&func) << std::endl;
}

int main()
{
Hoge<int> h(123);
Hoge<int> i(456);
func(h);
func(i);
}


327 名前: デフォルトの名無しさん 投稿日: 02/12/20 00:39
>>326
質問内容と貼り付けるソースを対応させてくれ。
ソースがいろんな(たぶん余計な)要素を含みすぎて
何を答えて欲しいのかがイマイチつかめん。

そのソースでエラーになるんだったら、&func<T>かなー?


328 名前: デフォルトの名無しさん 投稿日: 02/12/20 00:44
>>327
スマソ。いらない要素を除いて短くしました。まだエラーが出ます。
コンパイラはgcc3.2.1(MinGW)です。

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

template <typename T>
void func(Hoge<T>& t)
{
std::cout << reinterpret_cast<long>(&func<T>) << std::endl; //エラー
}

int main()
{
Hoge<int> h;
Hoge<int> i;
func(h);
func(i);
}


329 名前: デフォルトの名無しさん 投稿日: 02/12/20 00:55
さらに短くしました。friend宣言もクラス宣言も取ってしまいました。

template <typename T>
void func(T t)
{
std::cout << t << std::endl;
std::cout << reinterpret_cast<long>(&func<T>) << std::endl; //エラー
}

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


330 名前: デフォルトの名無しさん 投稿日: 02/12/20 01:13
329です。自己解決しました。
テンプレート関数は、コンパイラから関数のオーバーロードと解釈されるようです。
従って、関数名を正しくキャストする事によりうまくコンパイルできました。

template <typename T>
void func(T t)
{
std::cout << t << std::endl;
std::cout << reinterpret_cast<long>(static_cast<void (*)(T)>(func)) << std::endl; //うまく行く
}

int main()
{
func<int>(1);
func<double>(1);
func<int>(2);
}


331 名前: デフォルトの名無しさん 投稿日: 02/12/20 01:21
んーでも少し問題が。gcc3.2.1(MinGW)では通るものの、Borland-C++5.6.2では

エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<int>(int) )
エラー E2335 overload2.cpp 7: このコンテキストではオーバーロード 'func' が曖昧(関数 void func<double>(double) )

と言われてしまいました。Borland-C++が糞なのか、それとも私が何か間違っているのか?


332 名前: デフォルトの名無しさん 投稿日: 02/12/20 19:03
Modern C++ Design を読んで疑問に思ったので質問します
8章のオブジェクトファクトリのRegisterコールバック関数の登録についてです。
ある具象クラスLine(: public Shape)のソースにおいて
const bool registered = ShapeFactory::Instance().Register( LINE, CreateLine );
としてシングルトンのファクトリに登録していますが、
これはファクトリがシングルトンの場合にしかつかえないと思うのです。
動的にファクトリを生成・利用する場合には、具象クラスの情報を一ヶ所にまとめた物がどこかに必ず必要になると思うのですが、
この認識は正しいでしょうか?
シングルトンではなく、ファクトリになんの変更も無しに新たな具象クラスを追加する方法があるのでしょうか?


333 名前: デフォルトの名無しさん 投稿日: 02/12/20 21:52
VC.NETのSTLへの対応ってどんなもんなんですか?
VC6.0と同じ程度なんですか?
sort(v.begin(),v.end(),mem_fun_ref(&hoge::hoge)); ←こんなの通るの?


334 名前: デフォルトの名無しさん 投稿日: 02/12/21 01:28
>>332
Factoryクラスのstaticメンバに情報を持つか、FactoryのFactoryに
情報をまとめるようにして、Factoryの生成をライブラリ側で管理するか、
フリー関数のオーバーロードで頑張るかすれば、一応何とか出来るのではないかと。

しかし、ファクトリがSingletonでないことが必要な場合なら、
各々のファクトリが勝手に情報共有してしまったらむしろ
困ると思うのだけど、具体的にどういう場合を想定してるん?

>>333
> mem_fun_ref(&hoge::hoge)
いやコンストラクタをmem_funに渡せる実装はなかなか少ないだろう。

men_fun1_refにしないでも大丈夫になってるか?という意味なら、VC.NET 2002 ならOK。


335 名前: デフォルトの名無しさん 投稿日: 02/12/21 03:31
>>334
すいません、編集ミスです。<コンストラクタ
しかも、ペーストする場所を思いっきり間違えてました。
質問したいのは、これ(↓)でした。
find_if(v.begin(),v.end(),bind2nd(mem_fun_ref(&Hoge::hoge),HogeObject));

手元にg++用に書かれたコード(STL多用)があり、
これにGUI部分を実装しなければならないのですが、
VC6までは、STLがまともに動かないという話を聞いたことがあるので、
VC.NETではどうなってるのかなと思って質問しました。
やっぱり、BCB6の方が良いでしょうか?


336 名前: 332 投稿日: 02/12/21 05:27
>>334
疑問に思っていたのは以下の2点でした
・「シングルトン」及び「staticメンバに情報を登録」ではプログラムロード時からメモリに存在する。
・ファクトリ側では実行するまでどんな具象クラスが登録されるかを知らない形にし、各具象クラスのcppファイルで登録させる。

プログラムの流れでたまにしか出てこない、いろんな種類のファクトリをはじめからメモリに確保するのが嫌だったのです。
でも実行時に登録するには、
・コンパイラが自動的に実行してくれるグローバルな領域に置かれた命令による登録(シングルトンが必要)
・どこかにリストアップしておく。
のどちらかしか無いように思います。
用語が滅茶苦茶だと思いますがすいません。


337 名前: sage 投稿日: 02/12/21 05:37
>・コンパイラが自動的に実行してくれるグローバルな領域に置かれた命令による登録(シングルトンが必要)
グローバルはおかしいかな。
cppファイルの頭の部分に書く
const bool registered = Singleton::Register(objType,CreateCallback);
な感じのやつのことです。



338 名前: デフォルトの名無しさん 投稿日: 02/12/21 06:12
ファクトリの百や二百、メモリを使用してるうちに入らんと思える私は幸せなのでしょうか。


339 名前: 332 投稿日: 02/12/21 09:26
私もです。しかもせいぜい10個くらい。


340 名前: デフォルトの名無しさん 投稿日: 02/12/21 21:06
std::mem_fun_refってどういう時に使う?
std::mem_funは、仮想関数を呼び出す時に便利だが、std::mem_fun_refだと
クラスへのポインタではなく実体を渡さないといけないので、例えば

class A;
class B : public A;

のようになっているとして、

std::vector<A*> にはBへのポインタも格納できるが、std::vector<A>にBを
格納しようとすると未定義の動作となる。ポインタならばstd::mem_funで
呼び出せる。std::mem_fun_refは実体を渡さなければならないが、vector
に両方は格納できない。

だから、std::for_each()などで、std::mem_fun_refを使う状況というのがどう
いう場合なのか知りたい。


341 名前: デフォルトの名無しさん 投稿日: 02/12/21 21:52
>>340
Aが派生して使うような型じゃない場合。


342 名前: デフォルトの名無しさん 投稿日: 02/12/22 01:25
>>341
なるほど、こんな場合か。単純と言えば単純だな。

class A {
int j;
public:
void print(int i) {
std::cout << i + j << std::endl;
}
A(int k) : j(k) {}
};

int main()
{
std::vector<A> a;

a.push_back(A(1));
a.push_back(A(2));
a.push_back(A(3));

std::for_each(a.begin(), a.end(), std::bind2nd(std::mem_fun_ref(&A::print), 1));
}


343 名前: デフォルトの名無しさん 投稿日: 02/12/22 01:40
boost::anyと、std::mem_fun_refを使って仮想関数を呼び出そうとしたが
なかなかうまく行かない。

int main()
{
std::vector<boost::any> a;

a.push_back(A());
a.push_back(B());

std::for_each(a.begin(), a.end(), std::bind2nd(std::bind1st(std::mem_fun_ref(&A::print), boost::any_cast<A&>(this)), 1)); // だめ
}


344 名前: デフォルトの名無しさん 投稿日: 02/12/22 05:02
どうしてany_castに失敗するのでしょうか?

struct A {
void print() {
std::cout << "A" << std::endl;
}
};
int main()
{
std::vector<boost::any> a;

a.push_back(A());
a.push_back(A());

std::vector<boost::any>::iterator pos = a.begin();
try {
for (; pos != a.end(); ++pos)
boost::any_cast<A>(a).print();
}
catch (boost::bad_any_cast& e) {
std::cerr << e.what() << std::endl;
}
}


345 名前: デフォルトの名無しさん 投稿日: 02/12/22 08:52
>>343
試さずに書いてるが、
boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );

>>344
boost::any_cast<A>(*pos).print();
じゃねーの?


346 名前: 345 投稿日: 02/12/22 08:54
というか、今のバージョンのany_castって継承関係の把握できたっけ。


347 名前: デフォルトの名無しさん 投稿日: 02/12/22 09:49
Lokiのインストール法、誰か教えて。
英語読めん。
それと、iostreamをインストールすると、コンパイラ付属のは使えなくなるんか。
それはそれで不安だ。教えてくれ。


348 名前: デフォルトの名無しさん 投稿日: 02/12/22 11:19
>>347
DLして解凍して適当なフォルダに入れてインクルードパス通すだけ
というかあれくらいの長さのreadmeくらい読みなよ…

後環境も何も書いてないからこれ以上は無理


349 名前: デフォルトの名無しさん 投稿日: 02/12/22 11:45
Lindows


350 名前: デフォルトの名無しさん 投稿日: 02/12/22 19:33
>>345
ありがとうございます!

boost::compose_f_gx( boost::bind( &A::print, _1, 1 ), &boost::any_cast<A&> );
は通りませんでしたが、

boost::any_cast<A>(*pos).print();
は無事通りました。

boost::any_castは依存関係の把握はできないかもしれませんので、ポリモルフィズム
には使わないようにします。


351 名前: デフォルトの名無しさん 投稿日: 02/12/22 19:54
ところで C++ Templates [ http://www.josuttis.com/tmplbook/tmplbook.html ] は既出なのか?


352 名前: 名無しさん@Emacs 投稿日: 02/12/22 23:47
げ、ホントだ、any_cast ってポリモーフィズムに使えないんだ・・・
っつーか皆さん boost::any ってどんな時に使ってます?
イチイチ any_cast 噛まさにゃならん上にポリモーフィズム使えないもの
をどんな風に使うのか興味があるのですが・・・
# つまり馬鹿だから使い道が思い付かないわけでして。

struct A { virtual void print() { std::cout << "A" << std::endl; }};

struct B : public A{ virtual void print() { std::cout << "B" << std::endl; }};

int main()
{
std::vector<boost::any> a;

a.push_back(new A());
a.push_back(new B());

std::vector<boost::any>::iterator pos = a.begin();
try {
for (; pos != a.end(); ++pos) boost::any_cast<A*>(*pos)->print();
}
catch (boost::bad_any_cast& e) {
std::cerr << e.what() << std::endl;
}
}

output>
A
boost::bad_any_cast: failed conversion using boost::any_cast


353 名前: デフォルトの名無しさん 投稿日: 02/12/23 00:24
>>352
void* で汎用パラメータ渡し…とか、union でノードの種類を区別した
木構造…とかのtypesafeなバージョンとしては、とりあえず超高速で
お手軽に書こう、と思ったときには使えるかも。俺は使ったこと無いけど。

using namespace boost;
struct add { add(any l,any r):left(l),right(r){} any left, right; };
struct mul { mul(any l,any r):left(l),right(r){} any left, right; };

double eval_expr( any e )
{
if( e.type() == typeid(add) ) {
add ex = any_cast<add>(e);
return eval_expr( ex.left ) + eval_expr( ex.right );
} else if( e.type() == typeid(mul) ) {
mul ex = any_cast<mul>(e);
return eval_expr( ex.left ) * eval_expr( ex.right );
} else if( e.type() == typeid(double) ) {
return any_cast<double>(e);
} return any_cast<int>(e);
}

int main()
{
any expr = add( add(mul(6,7),2), mul(3,4) );
cout << eval_expr( expr ) << endl;
}

その手の使い方をするにしても、入れられる型に制限をつけた
variantとかの方がマシだしなぁ。


354 名前: デフォルトの名無しさん 投稿日: 02/12/23 02:06
>>351
any.hppの中身を見てみると、boost::any_castはキャストしようとする型と、
元のタイプのtypeidを比較して、一致しないとキャストしないようになっている。
だからポリモルフィズムに使えないんだろう。

-- any.hpp (STLpotrt)より

template<typename ValueType>
ValueType * any_cast(any * operand)
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}

std::mem_fun_refと組み合わせていろいろと面白い事をやらせようとしていた
のだが、使えねー。まあだめならだめで昨日から悩み続けていた事が解決
したのでいいのだが。


355 名前: デフォルトの名無しさん 投稿日: 02/12/23 02:07
スマソ>>354>>352さんに対するレスです。


356 名前: デフォルトの名無しさん 投稿日: 02/12/23 04:45
すごく簡単な所でつまづいています。どこがおかしいのでしょうか?

class A {
public:
void func(int i) {
std::cout << i << std::endl;
}
};

int main()
{
std::vector<A> a;

a.push_back(A());
a.push_back(A());

std::for_each(a.begin(), a.end(), std::compose1(std::mem_fun_ref(&A::func), 1);
}


357 名前: デフォルトの名無しさん 投稿日: 02/12/23 04:49
自己解決しました。うーん?直感的にはcompose1のような気がするのですが?
わからなくなってきた。

class A {
public:
void func(int i) {
std::cout << i << std::endl;
}
};

int main()
{
std::vector<A> a;

a.push_back(A());
a.push_back(A());

std::for_each(a.begin(), a.end(), std::bind2nd(std::mem_fun_ref(&A::func), 1));
}


358 名前: デフォルトの名無しさん 投稿日: 02/12/23 05:26
こんな簡単なプログラムがコンパイルできません。どこがおかしいのか
わかりますか?コンパイラはgcc3.2.1です。

int main()
{
double ad[] = {0.5, 1.0, 1.5};
std::vector<double> d(ad, ad + 3);

std::transform(d.begin(), d.end(), std::ostream_iterator<double>(std::cout, " "), std::sin);
}


359 名前: デフォルトの名無しさん 投稿日: 02/12/23 06:35
358です。非常に不本意ながら、自己解決しました。
#include <cmath>を#include <math.h>にして、std::sinをsinにすれば通ります。

しかし、ここで当然疑問が沸きます。なぜstd名前空間に包まれているsinが
std::transformに適用できないのか、どうしてもわかりません。何のための
<cmath>なんでしょうか?


360 名前: デフォルトの名無しさん 投稿日: 02/12/23 08:05
>>356-357
compose1 というのは、返値を h = compose1( f, g ) とすると
h(x) が f( g(x) ) と同じ意味になる合成のことなわけだが。
たぶん貴方の場合、std::mem_fun_ref(&A::func) が2変数関数だし、
1 というのは関数ですらないので全然ダメ。

ついでに1変数メンバ関数用の mem_fun_ref は g = mem_fun_ref( f ) とすると
g(x, y) と x.*f(y) が同じ意味になるもので
bind2nd というのは g = bind2nd( f, c ) とすると
g( x ) が f( x, c ) と同じ意味になるものなので期待通りになる。


361 名前: デフォルトの名無しさん 投稿日: 02/12/23 09:40
>>359
C では double sin(double x); しかないが、C++ では
double sin(double x);
float sin(float x);
long double sin(long double x);
とオーバーロードされてて、どれかわからんので困ってるのでは?


362 名前: デフォルトの名無しさん 投稿日: 02/12/23 15:01
>>361
なるほどありがとうございます。キャストしたら通りました。引数が
doubleだからつい自動判別してくれると期待していたのですが、
アルゴリズム中では正しく働かないようですね。

int main()
{
double ad[] = {0.5, 1.0, 1.5};
std::vector<double> d(ad, ad + 3);

std::transform(d.begin(), d.end(), d.begin(), static_cast<double (*)(double)>(std::sin));
}


363 名前: デフォルトの名無しさん 投稿日: 02/12/23 19:22
typedef struct
{
int id;
double value;
} BANK;

std::list<BANK> blist;

みたいなlistがあって、こいつを構造体BANKの中のvalueの値で
sortしたい(valueの値が大きい順に)場合、どうしたらよいのでしょうか?
blist.sort()を使う方を教えてください!!


364 名前: デフォルトの名無しさん 投稿日: 02/12/23 19:25
>>363
sortに引数を渡せ。


365 名前: 352 投稿日: 02/12/23 19:27
>>353,354
むむむ、なるほど。情報サンクスコ
なんか大抵の場合はポリモーフィズムかテンプレート使えばいい感じですなぁ・・・
>>853氏の例をちょっといぢってみたんだけど、 6 を 6.0f にするだけで氏ぬのね。
typeid 使うとこの辺(double, float とかポリモーフィズムとか)が問題になって来るわけか。
なるほど、なるほど。勉強になりますた。


366 名前: デフォルトの名無しさん 投稿日: 02/12/23 19:38
>>364
引数の書き方がわからないです。教えてくらはい。


367 名前: デフォルトの名無しさん 投稿日: 02/12/23 19:44
>>366
よーし、SGIのとこからもってきてやったぞ、ホレ。

template<class BinaryPredicate>
void sort(BinaryPredicate comp);

Comp must be a comparison function that induces a strict weak ordering (as defined in the LessThan Comparable requirements on objects of type T.
This function sorts the list *this according to Comp.
The sort is stable, that is, the relative order of equivalent elements is preserved.
All iterators remain valid and continue to point to the same elements.
The number of comparisons is approximately N log N, where N is the list's size.


368 名前: デフォルトの名無しさん 投稿日: 02/12/23 19:48
>>366

struct BANK {
int id;
double value;
BANK(int i, double d) : id(i), value(d) {}
};

inline bool Cmp(BANK a, BANK b)
{
return a.value > b.value;
}

int main()
{
std::list<BANK> blist;

blist.push_back(BANK(1, 1.1));
blist.push_back(BANK(2, 3.3));
blist.push_back(BANK(3, 2.2));

blist.sort(Cmp);

std::list<BANK>::iterator pos = blist.begin();
while (pos != blist.end())
std::cout << pos->id << ", " << pos++->value << std::endl;
}


369 名前: デフォルトの名無しさん 投稿日: 02/12/23 20:03
363、366です。
わかりました!!
これで明日のミーティングに間に合いそうです。
みなさんありがとうございました。


370 名前: デフォルトの名無しさん 投稿日: 02/12/23 20:22
C++のSTLには、叙述関数と関数オブジェクトの2種類があって、互いに
よく似ているために未だに混同します。

例えば関数オブジェクトは内部状態を持っていてそれを変化させても
いいようですが、叙述関数は呼び出しの度に内部状態を変化させては
ならないと規定されているようです。

皆さんはどうやって区別していますか?


371 名前: デフォルトの名無しさん 投稿日: 02/12/23 20:24
370です。(゚Д゚)ハァ?なことを書いてしまってすみません。

叙述関数は、ブール値を返す関数または関数オブジェクトでした。
で、やっぱり関数オブジェクトも内部状態を変化させない方がいいの
でしょうか?


372 名前: デフォルトの名無しさん 投稿日: 02/12/23 21:04
> 呼び出しの度に内部状態を変化させてはならないと規定
これどこで規定されてんの?


373 名前: デフォルトの名無しさん 投稿日: 02/12/23 23:16
>>372
「規定」と書くと語弊がありますね。C++標準ライブラリ日本語版§8.1.4、P297
に「叙述関数と関数オブジェクトの違い」という節があり、内部状態を変化させ
る関数オブジェクトを叙述関数として使うと、予想に反した動作をする例が書か
れています。

つまり、constな関数オブジェクトでないと、予想した動作ではなくなる可能性
があるという事ですね。


374 名前: デフォルトの名無しさん 投稿日: 02/12/23 23:22
>>373
その記述がすべてだな。「可能性がある」ってんだから、
あとは、場合による、としか言えないんじゃないの。


375 名前: デフォルトの名無しさん 投稿日: 02/12/23 23:29
>>374
簡単にまとめると次のようになりますかね。

叙述関数:
  bool値を返す関数または関数オブジェクト。但し、呼び出し毎に内部状態
  が変化する関数または関数オブジェクトは、標準アルゴリズムに適用する
  と予想に反した動きをする可能性があるので、できるだけ使用しない方が良い。


376 名前: デフォルトの名無しさん 投稿日: 02/12/23 23:45
>>375
まとめるのは勝手だが、
「可能性があるので」が理由じゃぁまとまってるとは言い難い。


377 名前: デフォルトの名無しさん 投稿日: 02/12/24 00:14
>>376
やっぱり「可能性」の具体例をあげないとダメか・・・・
本を読んでくれ、なら簡単なんだが、自分でまとめるとなると、何か例を
考えないといけないか。


378 名前: デフォルトの名無しさん 投稿日: 02/12/24 02:08
関数を提供する側から言えば、
副作用がない、と仮定してアルゴリズムが書かれていると、
述語(ここで言えば叙述関数)を呼び出す回数が予想できないわけだ。

副作用がないなら同じ引数で何度呼んでも値は同じはずだから、アルゴリズムは返り値をメモり、以降その値を使いまわすかもしれない。
(しかし副作用がある関数は呼ばれるごとに値が変わることができるから、メモった値と呼んで帰った値は一致しない可能性がある。)
このような性質はアルゴリズム内に隠蔽されていて関数提供側ではまったく予想できない。

一方、逆に標準アルゴリズムを提供する側から言えば、
述語は条件判定に使う関数だから、
例えば副作用がコンテナ内の要素に影響を及ぼす類のものだとすると結果は破壊的になりうるし、そうでなくても同じ対象を比較する際に呼び出すごとに違った値を返すとすると
それらを仮定してアルゴリズムを書くのは大変困難だ。

ひどい例を考えてみる。あるコンテナをソートするとする。
そのときにソートの比較に使う述語(if文の中で比較・判別に使われる)が
大小判定ついでにコンテナの値を書き換えるとすると、
どんなアルゴリズムでも大前提(ソート中に値が変化しない)が崩れるから
ソートはまずまともに機能しないだろう。
(終わらなくなったり、正しくない結果を返したり・・・。)

述語というのは論理学用語だが、
基本的にif文(あるいはfor文など)の条件式内で条件判定に使われる
特殊な種類の関数をさす用語。
普通、if文の中で代入や入出力などするコードはあまりお行儀が良いとは言えない
分かりにくい保守・変更しにくいコードだという事は納得してもらえると思う。それと同じ。
(エラー処理のように条件が成立したら処理を中止するような場合はともかく。)

一方、述語(叙述関数)は関数オブジェクトの中でも特殊なものなので、
一般の関数オブジェクトの在り様まで規制するものではないから、一般の関数オブジェクトは副作用があっても良い。っつーか、むしろないと困るものもあるくらいだろう。


379 名前: デフォルトの名無しさん 投稿日: 02/12/24 09:20
map のコンストラクタで、比較オブジェクトを引数にとるものがあるが、
それの存在意義がわからない。

プログラミング言語C++ 第3版 17.4.1.5
void f(map<string,int>& m)
{
  map<string,int> m2; // デフォルトで < を使う
  map<string,int> m3(m.key_comp()); // mの比較基準を使う
}

とあるが、m.key_comp() は less<string> だから、
デフォルトの < を使うのと同じこと。
比較オブジェクトをコンストラタに渡すのが有意義な場合ってある?


380 名前: デフォルトの名無しさん 投稿日: 02/12/24 09:34
>>379
キーが整数として、比較基準を、ある基準値との差の比較とすると、
比較オブジェクトの中に基準値を入れて使うことが想定できる。

struct compare_distance
{
  const int origin;
  compare_distance(int org):origin(org){}
  bool operator() (int rhs, int lhs) const
  {
    return std::abs(rhs - origin) < std::abs(lhs - origin);
  }
};



381 名前: デフォルトの名無しさん 投稿日: 02/12/24 09:53
>>380 なるほどね。そういう例はわかります。その比較オブジェクトを渡す
mapの型は map<int, T, compare_distance> ですよね。
map<int, T> つまり map<int, T, less<int> > に、渡せるわけではないと。



382 名前: デフォルトの名無しさん 投稿日: 02/12/24 16:35



383 名前: デフォルトの名無しさん 投稿日: 02/12/24 23:38
これこそ型志向言語の神髄中の神髄、C++が最晩年に到達した
何にも真似のできない世界です。このライブラリに込められた
テンプレートの技法は、後世のどの言語もついに超えることが
ありませんでした。ですから現在でもこのライブラリはテンプ
レートの最高の技術を示した作品であり続けています。
C++の晩年には、テンプレートを駆使した手法は時代遅れとなっ
ており、手厳しい非難の対象にもなっていました。しかしC++は
テンプレートを捨てることなく、むしろテンプレートの限界を
極めるような作品を数多く生むようになります。その最高の成
果が、この「Loki」で、たった1つの主題の技法の可能性を徹
底的に汲み尽くした(残念ながらC++の死によって未完となって
いますが)作品となっています。加えて、ソースにコンパイラ
の指定がなく、そのためにVC++版、g++版、Comeau版など、いろ
いろでコンパイラに実装が試されています


384 名前: デフォルトの名無しさん 投稿日: 02/12/24 23:41
>383 バッハの『フーガの技法』の解説のパクリかい?


385 名前: デフォルトの名無しさん 投稿日: 02/12/25 00:34
>384 よく知ってるね
おれの中では両者の間に連想がある。なんというか厳格さと
柔軟さの混在というか...
でももしC++が廃れるようなことがあれば、テンプレートを
魔術的に駆使したものはフーガの技法みたいな扱いを受けそう。


386 名前: デフォルトの名無しさん 投稿日: 02/12/25 01:52
過去の難解言語で為された魔術が
今どういう扱いを受けているか考えてみるといい


387 名前: デフォルトの名無しさん 投稿日: 02/12/25 15:00
最近知ったのですが、boost面白そうですねぇ。
俺の場合、STLとかからちゃんと勉強しないといけないけど(笑)

ところで、boostのfunctionalとかfunctionって、メンバ関数に対しても使えるの??



388 名前: デフォルトの名無しさん 投稿日: 02/12/25 16:44
STLはスレッドセーフですか?そうでないとしたらスレッドセーフなコンテナはありますか?


389 名前: デフォルトの名無しさん 投稿日: 02/12/25 19:17
↑よく知らないけど純粋にテンプレートだけじゃないんですか???


390 名前: デフォルトの名無しさん 投稿日: 02/12/25 19:18
>>388
「このコンテナはスレッドセーフである」と規格に書かれてたりは、しないと思う(たぶん)。実装に依存すると考えるべきではないかなぁ?


391 名前: デフォルトの名無しさん 投稿日: 02/12/25 22:00
Effective STL の Item 12 が "Have realistic expectations about the thread
safety of STL containers." となっているのでこれを読んでみては?


392 名前: デフォルトの名無しさん 投稿日: 02/12/26 00:22
>>387
メンバ関数は第一引数にインスタンスのポインタを
渡してやればいいから、こんな感じ。
#include <iostream>
#include "boost/function.hpp"
#include "boost/bind.hpp"
struct Test {
int t_;
Test(int t) : t_(t) {}
int Add(char t) {return t_ + t;}
};
int main() {
Test test(5);
boost::function1<int, char> func;
func = boost::bind(&Test::Add, &test, _1);
boost::function2<int, Test *, char> func2;
func2 = &Test::Add;
std::cout << (func)(6) << std::endl;
std::cout << (func2)(&test, 6) << std::endl;
}



393 名前: デフォルトの名無しさん 投稿日: 02/12/29 16:46
Boost!

ワル カコイイ(・∀・)!


394 名前: デフォルトの名無しさん 投稿日: 02/12/29 19:12
boost::formatの戻り値をchar*として受け取ってメッセージボックスに
表示したいのですがいい方法は無いですか?
()でくくってc_str()とかやってみましたが、
error C2039: 'c_str' : 'boost::basic_format<Ch,Tr>' のメンバではありません。
[
Ch=char,
Tr=std::char_traits<char>
]
と怒られてしまいます。

MessageBox(NULL, (boost::format("Error !!!\n"
"\tlocation %d:%d\n"
"\tcode %02x:%02x:%02x:%02x\n"
"\tmessage %s\n") %
parse_error->get_line() %
parse_error->get_row() %
parse_error->get_genre() %
parse_error->get_category() %
parse_error->get_sequence() %
parse_error->get_sequence_case() %
parse_error->get_message()).c_str(),
"error", 0);


395 名前: デフォルトの名無しさん 投稿日: 02/12/29 20:03
(...).str().c_str() しかないんでない?


396 名前: 393 投稿日: 02/12/29 21:54
SGIには感動した!
精子出た!
ropeキター


397 名前: デフォルトの名無しさん 投稿日: 02/12/29 22:31
Modern C++ Designの19ページの一番下に紹介されてる
「極めて洒落たテクニック」のソースきぼーん
"Sutter"とか"copy constructor"とかで検索したけど
みつからんかった...


398 名前: デフォルトの名無しさん 投稿日: 02/12/29 22:55
>>397
Exceptional C++ の項目13。


399 名前: デフォルトの名無しさん 投稿日: 02/12/29 23:46
>>397
Loki::SmartPtr::operator=()を見たらいいやんって書いてあるやん。


400 名前: デフォルトの名無しさん 投稿日: 02/12/30 15:40
boost使うとコンパイル劇遅で、ノートな私はVCが死んだかと
思ってしまいます。
コンパイルを早くする方法ってないのかな?
templateだからやっぱ無理?


401 名前: デフォルトの名無しさん 投稿日: 02/12/30 16:08
>>400
プリコンパイル


402 名前: デフォルトの名無しさん 投稿日: 02/12/30 17:33
>>401
「プリコンパイルヘッダの使用」とかいうやつ?


403 名前: デフォルトの名無しさん 投稿日: 02/12/30 18:06
gcc-3.6ぐらいにはpchブランチの成果が取り込まれるといいな


404 名前: デフォルトの名無しさん 投稿日: 02/12/30 20:29
>>402
ttp://www1.kcn.ne.jp/~robe/cpphtml/html03/cpp03003.html

この辺が参考になると思う。


405 名前: デフォルトの名無しさん 投稿日: 03/01/02 22:01
GenScaterHierarchyについてわからない点。

template <class T1, class T2, template <class> class Unit>
class GenScaterHierarchy<TypeList<T1, T2>, Unit>
: public GenScatterHierarchy<T1, Unit>
: public GenScatterHierarchy<T2, Unit>
{
・・・・・
};

最初の(左側の)基底クラスはGenScatterHierarchy<T1, Unit>としなくても、

template <class T1, class T2, template <class> class Unit>
class GenScaterHierarchy<TypeList<T1, T2>, Unit>
: public Unit<T1>
: public GenScatterHierarchy<T2, Unit>
{
・・・・・
};

のようにUnit<T1>でいいのでは?


406 名前: デフォルトの名無しさん 投稿日: 03/01/06 02:49
保守


407 名前: デフォルトの名無しさん 投稿日: 03/01/06 03:44
>>405
それだと継承ツリーの途中で Unit<T1> を複数回継承することになって、
コンパイルエラー食らわん?


408 名前: デフォルトの名無しさん 投稿日: 03/01/06 13:35
>>407
そ、そうかな... ;


409 名前: デフォルトの名無しさん 投稿日: 03/01/06 16:31
何かネタない?


410 名前: デフォルトの名無しさん 投稿日: 03/01/06 16:37
http://groups.yahoo.com/group/boost/files/utf/
暇ならこれチェックして


411 名前: デフォルトの名無しさん 投稿日: 03/01/06 21:02
std::map<int, std::string>に値を挿入するには、

insert(std::map<int, std::string>::value_type(1, "abc"))

insert(std::pair<int, std::string>(1, "abc"))
のどちらがより適切でしょうか?


412 名前: デフォルトの名無しさん 投稿日: 03/01/06 21:10
>>411
同じ。mapのvalue_typeは、pairをtypedefしたもの。


413 名前: デフォルトの名無しさん 投稿日: 03/01/06 21:12
>>412
それはわかってるんじゃないか?


414 名前: デフォルトの名無しさん 投稿日: 03/01/06 21:21
>>413
Borland-C++5.6.2でコンパイルしてみた所、同じようなコードを吐いているようです。
コンパイラが違うとバイナリも違ってくるかもしれませんが。
ただ、タイプ量が少ないstd::pairの方が多用される傾向にあると思います。

もっともmap<int, std::string>をtypedefして使えばどちらもあまり変わらないですね。


415 名前: デフォルトの名無しさん 投稿日: 03/01/07 00:25
>>411
insert(std::make_pair(1, "abc"))


416 名前: デフォルトの名無しさん 投稿日: 03/01/08 14:25
std::wifstream win("in.txt");
std::wofstream wout("out.txt");
wout << win.rdbuf();
wout.close();
win.close();

マルチバイトを使おうとおもってテストでこれやってみたのですが、
0x81で始まる、日本語がうまく表示されないんですけど
ベターな解決策おしえてください。

win2000 vc6 stlport使用 です。


417 名前: デフォルトの名無しさん 投稿日: 03/01/08 14:29
>>415
411です。
遅くなりましたがありがとうございます。make_pairという述語があるのですね。


418 名前: デフォルトの名無しさん 投稿日: 03/01/08 14:39
>>416
stlに関係ないじゃん。(V)C++スレにゆくべきかと。
ちなみにマルチバイトとwchar_tは別物。


419 名前: デフォルトの名無しさん 投稿日: 03/01/08 16:59
1)string str="hoge";vector<string> vec;
2)vec.push_back(str);
3)str="fuga";

ここで2)でvectorに追加されているのはstrそのものでしょうか
あるいはそのコピーでしょうか?
また3)では2)でvectorに登録された内容は上書きされてしまうのでしょうか


420 名前: デフォルトの名無しさん 投稿日: 03/01/08 17:03
>>419
当然コピーです。3)で代入しても、vectorの中身には何の影響も及ぼしません。


421 名前: 419 投稿日: 03/01/08 17:07
>420
ありがとうございます。いろいろ試してみます


422 名前: 416 投稿日: 03/01/08 18:13
>>418
そっかー、そりはショック。
首つって、VCスレいってきます。
ありがとございました。


423 名前: IP記録実験 投稿日: 03/01/08 21:28
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/

1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。

27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?

38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27
鋭いです。

73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。


424 名前: デフォルトの名無しさん 投稿日: 03/01/08 22:29
保守


425 名前: デフォルトの名無しさん 投稿日: 03/01/09 00:38
>>1=無職
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww


426 名前: デフォルトの名無しさん 投稿日: 03/01/09 00:59
>>296
確かに民放じゃやらないですな。
BSではたまにやるけど。


427 名前: デフォルトの名無しさん 投稿日: 03/01/09 01:19
>>405
またポリタンコですか
あいつどうしようもないですね。


428 名前: デフォルトの名無しさん 投稿日: 03/01/09 01:31
あ、どーしてもいいたかったんだけど、

  絶 対 に 有 料 化 し な い で ね 。


429 名前: IP記録実験 投稿日: 03/01/09 01:59
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/

1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。

27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?

38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27
鋭いです。

73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。


430 名前: デフォルトの名無しさん 投稿日: 03/01/09 02:06
>>638
そのキャップだけはいろんな意味で許せん。僕によこせ


431 名前: デフォルトの名無しさん 投稿日: 03/01/09 02:46
>>56
Jane使えば一目瞭然


432 名前: デフォルトの名無しさん 投稿日: 03/01/09 03:33
匿名匿名掲示板自体にクレームがついたんだから2chじゃ出来ないでしょ。。。




連続書き込み規制変えたな

きつい。。。


433 名前: デフォルトの名無しさん 投稿日: 03/01/09 12:26
暴力団に殺人依頼した。管理人を入廷時に射殺する


434 名前: デフォルトの名無しさん 投稿日: 03/01/09 16:28
age


435 名前: デフォルトの名無しさん 投稿日: 03/01/09 17:18
======2==C==H======================================================

         2ちゃんねるのお勧めな話題と
     ネットでの面白い出来事を配送したいと思ってます。。。

===============================読者数: 138720人 発行日:2003/1/9

年末年始ボケがそろそろ収まり始めた今日このごろのひろゆきです。

そんなわけで、年末に予告したIP記録ですが実験を開始しています。

「2ちゃんねる20030107」
こんな感じで各掲示板の最下部に日付が入ってるんですが、
20030107以降になってるところはログ記録実験中ですー。

んじゃ!

────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50
────────────────────────────


436 名前: デフォルトの名無しさん 投稿日: 03/01/09 23:10
>>773-774
迂闊にもワラタ


437 名前: デフォルトの名無しさん 投稿日: 03/01/10 01:00
>>589
ちょっと違うが今までがそんな感じだったんよ。
「(善意であろうが悪意であろうが)確認できない以上利用者が真偽を判断すべきであり、
要請があっただけで全て削除するべきではない。」
というのがひろゆきの主張。
嘘を嘘と〜の名言もこれに繋がる。

これに対して動物病院訴訟における地裁・高裁の判断は、
「外部から確認できない以上当事者が中傷だと主張し削除の要請をした場合は、管理人は削除すべき。」

今後はこれに倣い当事者側が中傷だと主張さえすればIP公開する必要が出るかもしれない。
(もちろん警察なり裁判所の正式な提出要請があってからになるだろうけど)
なお、書き込んだ者はその書き込みに対し責任を負うべし、ってのは賛成だが。
いずれにしろ善意の告発は難しくなると思われ。


438 名前: デフォルトの名無しさん 投稿日: 03/01/10 09:39
>>104
と思うんだけど、某○○さんは違うという。。。


439 名前: デフォルトの名無しさん 投稿日: 03/01/10 10:00
>>104
と思うんだけど、某○○さんは違うという。。。


440 名前: デフォルトの名無しさん 投稿日: 03/01/10 10:19
>内容証明が届いて、すぐに削除したら、賠償はしなくていい気が。

それはそのとおりでしょうねぇ。

・内容証明が届いて、名誉毀損の書き込みがあることを知りえた
・その日から起算してン日間書き込みを消さなかった
・その間のン日間は名誉が毀損されたことによって被害が発生した
ということを「裁判所が認めれば」負けちゃうんじゃないかなぁ、、

>んだったら、IP取ってない板で、自分で自分を中傷して、
>すぐに裁判すれば賠償金が取れるってことになっちゃう、、

そのとおりじゃないすかねぇ、、
掲示板の持ち主がけんすうさんだという前提でいうと、
その中傷発言が自作自演かどうか、けんすうさんにも判断できないん
だったら、けんすうさんが責任を負わないといけないという判決ですよね。
しかし個人の中傷発言だったら最初から消せばいいのでは。。


441 名前: デフォルトの名無しさん 投稿日: 03/01/10 10:52
ガイドライン読めないのに獣医になれる世の中・・・


442 名前: デフォルトの名無しさん 投稿日: 03/01/10 11:34
2ちゃんねるに近いあるインターネット関連会社の社長は、
2ちゃんねるの幹部から得た話として証言する。
「2ちゃんねるは、運営者や幹部などが
それぞれ別々に会社を作りカネの流れを見え難くしているが、
実際の資金源は複数の大手通信会社系からの調査費名目のカネ。
月額で計約700万円と言い、年間にすれば1億円近く。
額はともあれ、これは通信会社系的には、
ぼう大なトラフィックを調査すると言う表向きの理由が一応は立つ。
自社系に都合の悪い書き込みがされた時に優先的に削除してもらうことも期待している」と前置きし
「通信会社系の削除の期待も含めて、2ちゃんねるは総会屋と同じになっている」と言うのだ。



443 名前: デフォルトの名無しさん 投稿日: 03/01/10 12:02
IPでも記録されてみるか。


444 名前: デフォルトの名無しさん 投稿日: 03/01/10 12:54
>>540
鑑定スレでお願いしようとして誤爆し・ま・す・た・!   


445 名前: デフォルトの名無しさん 投稿日: 03/01/10 13:09
C++にevalが仕様として盛り込まれるのは何年ぐらいでしょうか?


446 名前: デフォルトの名無しさん 投稿日: 03/01/10 15:18
ぼらんちあさんにお年玉です。
( ´∀`)ノ~●●●●


447 名前: デフォルトの名無しさん 投稿日: 03/01/10 15:36
>>445
cbrtが標準math functionsに組み込まれてから10年は必要です。


448 名前: デフォルトの名無しさん 投稿日: 03/01/10 15:47
名前(アルファベット)五人分入力
         ↓
     辞書式に並び替える
         ↓
  "meido.doc"ファイルに書き込む
というプログラムを教えてください。
まじ困ってます。



449 名前: デフォルトの名無しさん 投稿日: 03/01/10 15:53
>>441
2ちゃんねらでもPGなれるんだもん・・・。
糞だね。


450 名前: デフォルトの名無しさん 投稿日: 03/01/10 16:17


今後、予想されるレス

「IPって何ですか?」

「串って何ですか?」 「串揚げ」




451 名前: デフォルトの名無しさん 投稿日: 03/01/10 22:41
第3者が見て情報価値の低い書きこみ>「質の低い」


452 名前: デフォルトの名無しさん 投稿日: 03/01/10 22:49
匿名性に絡む問題なので反対 28% 1193 票
サイトのためになるから賛成 54% 2315 票
利用しないから関係ない 8% 378 票
2ちゃんねるってなに? 4% 172 票
アクセスログってなに? 4% 173 票






453 名前: デフォルトの名無しさん 投稿日: 03/01/10 23:45
そーいや boost::shared_ptr が policy 使うよーになるとか
ならんとかって話はどーなった?


454 名前: デフォルトの名無しさん 投稿日: 03/01/11 00:15
君がそれやればなんとかなるかも(^_^;)


455 名前: デフォルトの名無しさん 投稿日: 03/01/11 09:38
ますます、ファンタスティックでスリリングでドラマティックなスレッドですわね、


456 名前: デフォルトの名無しさん 投稿日: 03/01/11 09:39
713 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/09 15:33 ID:Jx8vAdAb
というわけで、掲示板の最下部のバージョン表示が20030107a以降のやつは、
ログとり実験やってますです。
今のところ、qb,live2,tmpですね

722 名前:心得をよく読みましょう 投稿日:03/01/09 15:43 ID:b1s0ydcx
qb : 2ch批判要望 削除議論 削除要請 削除整理
live2 : ニュース速報
tmp : ニュース極東 ちくり裏事情 政治思想 Download
    厨房! 人権問題 バカニュース 薬・違法
    ゴーマニズム ロビー 最悪 少年犯罪
    違反の潰し方 ペット苦手 なんでもあり 学歴

IP記録実験PART2
http://qb.2ch.net/test/read.cgi/accuse/1042020193/



457 名前: デフォルトの名無しさん 投稿日: 03/01/11 10:11
======2==C==H======================================================

         2ちゃんねるのお勧めな話題と
     ネットでの面白い出来事を配送したいと思ってます。。。

===============================読者数: 139038人 発行日:2003/1/10

なにやら、連日メルマガだしてるひろゆきです。

そんなわけで、ログ記録実験ですが、いちいちサーバ指定するのが面倒なので、
全部のサーバに入れてみました。

重くなって落ちたりしてもご愛嬌ってことで。。。

んじゃ!

────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50
────────────────────────────


458 名前: デフォルトの名無しさん 投稿日: 03/01/11 11:05
つうか、2chとアップローダーは関係無いだろに。


459 名前: デフォルトの名無しさん 投稿日: 03/01/11 11:35
雑談系やニュース系の板はIDもIPも関係ないわな


460 名前: デフォルトの名無しさん 投稿日: 03/01/11 12:37
(^^)


461 名前: デフォルトの名無しさん 投稿日: 03/01/11 13:09
ひろゆきはあほ
氏ね


462 名前: デフォルトの名無しさん 投稿日: 03/01/11 15:57
【予告】小学生の登校を狙って・・・
http://live2.2ch.net/test/read.cgi/news/1042035002/

674 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 23:36 ID:1BXnvYvY
通報する人は、IPはあるので管理者に連絡してくれれば、
「捜査関係事項照会書で照会しますよー」って言ってたて伝えてくださいー。

902 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 23:41 ID:1BXnvYvY
>警視庁の情報提供っていうフォームで通報していいですか?

フォームでもよいかと。
通報者の電話番号とかもきちんとかいといたほうが
取り上げられる可能性高いです。
ホントは110のほうがいいんですが、、


463 名前: デフォルトの名無しさん 投稿日: 03/01/11 16:02
IP記録スレは有るよ

IP記録実験2
http://news2.2ch.net/test/read.cgi/newsplus/1042030554/



464 名前: E 投稿日: 03/01/11 18:23

ある object が 型T のインスタンスだったときに true を返す
Javascript の instanceof みたいなモノを作ってみたんだけど、
イマイチ使用する場面を思い浮かばない。

なんかイイ使い方があったら教えて下さい


465 名前: デフォルトの名無しさん 投稿日: 03/01/11 21:19
>>464
蛇足ですがinstanceof演算子はJScriptですよん。


466 名前: デフォルトの名無しさん 投稿日: 03/01/11 22:22
>>464
それって
 #define instanceof(T, obj) (typeid(obj) == typeid(T))
とか
 template<class T> struct instanceof {
  static bool f( T ) { return true; }
  template<class U> static bool f( U ) { return false; }
 };
とかで十分な気がするんだけど、どんなもんを作ったん?
いまいちよくわからん。

>>465
JavaScript 1.3 以上にはあるよ。ECMAの標準にも入ってるし。


467 名前: 464 投稿日: 03/01/11 23:10
>>466
あ、そういえば、それでイイじゃん。つーか、そっちの方がいいかも。
俺が作ったのは、こんなモノ

class __object
{
 template< typename Type > struct holder
 {
  static holder* unique()
  {
   static holder obj;
   return obj;
  }
 };
public:
 template< typename InstanceType > __object( InstanceType& ) throw()
  : p_( holder<InstanceType>::unique() )
 {}
 template< typename CompareType > bool instanceof() const throw()
 { return p_ == holder<CompareType>::unique(); }
private:
 void* p_;
};

で、こう使う。
if( __object( obj ).instanceof<T>() ){ ... }


468 名前: 464 投稿日: 03/01/11 23:23
>>467 にミス。

class __object
{
 template< typename Type > struct holder
 {
  static holder* unique()
  {
   static holder obj;
   // ×return obj;
   return &obj;
  }
  ...

boost::any みたいなものに組み込めば面白いかなとも思ったけど、
type() があるからいらんわなー。
なんか1日無駄に過ごした気分。フゥ


469 名前: デフォルトの名無しさん 投稿日: 03/01/12 02:24
何を今更・・・


470 名前: デフォルトの名無しさん 投稿日: 03/01/12 02:28
ヤツがアニヲタという事がわかるな。


471 名前: デフォルトの名無しさん 投稿日: 03/01/12 02:55
どうしても解決できないので教えて下さい。

struct person{
int id;
std::string name;
};

struct personless
{
bool operator()( const person & l, const person & r ) const {
return (l.id < r.id);
}
bool operator()( const person & l, const int & r_id ) const {
return (l.id < r_id);
}
bool operator()( const int & l_id, const person & r ) const {
return (l_id < r.id);
}
};
typedef std::set<person, personless> PersonSet;

このとき
PersonSet ps;
PersonSet::iterator it = ps.find( 5 );

というように、findすると下のようなエラーがでます。
error C2663: 'find' : 2 オーバーロードに 'this' ポインタのための必要な定義がされていません。

これはどうしたら解決できるんでしょうか?


472 名前: デフォルトの名無しさん 投稿日: 03/01/12 03:21
>>471
こんな風にしてもダメ?

struct person {
int id;
std::string name;
person(int i, char* str) : id(i), name(str) {}
};

// 途中略

int main()
{
PersonSet ps;
ps.insert(person(1, "def"));
ps.insert(person(5, "abc"));
PersonSet::iterator it = ps.find(person(5, "abc"));
std::cout << it->id << ' ' << it->name << std::endl;
}


473 名前: 471 投稿日: 03/01/12 09:17
>472
ええと、IDで検索するのが目的なのでこれではちょっと。
int一つ分冗長になるけれど
std::map<int ,person>
とするしかないのかな。


474 名前: デフォルトの名無しさん 投稿日: 03/01/12 09:35
>>473
VC++(だよね?)付属のSTLをやめて STLport を入れれば解決するらしい。
http://www.google.co.jp/search?q=cache:ucnz7QO5270C:www.dodgson.org/lab/hat/map_like_set.html&hl=ja&ie=UTF-8

でなければ、setの中身オブジェクトの作成コストが低ければ
PersonSet ps;
...
person key = { 5, string("") };
PersonSet::iterator it = ps.find( key );
みたいにダミーのオブジェクトで検索…くらいしかないのではないかなぁ。


475 名前: デフォルトの名無しさん 投稿日: 03/01/12 09:47
 4nd
フォンドボー?


476 名前: デフォルトの名無しさん 投稿日: 03/01/12 09:47
馬鹿が喜ぶだけだからニュースにするなよ


477 名前: 471 投稿日: 03/01/12 10:32
>>474
そのページ既に見てたのですが一番下のコード、コンパイルとおりますか?
ウチの環境VC6+STLportだと >>471 に示したエラーが出るんです。

って書いてたのですが、Releaseでコンパイルしたら通りました。
デバッグ時にわざわざ
#define_STLP_DEBUG 1
を定義してたのがダメだったようです。コメントアウトしたらデバッグでも
コンパイル通りました。
納得いかないけど解決手段として _STLP_DEBUGを使うのはあきらめます。


478 名前: デフォルトの名無しさん 投稿日: 03/01/12 11:19
>>473
std::setのfindはkeyそのものを探すので、IDで検索したければ、
std::mapのようにkeyとvalueが分離されているコンテナを使った
方がよい。std::setは明らかに不適。


479 名前: デフォルトの名無しさん 投稿日: 03/01/12 11:41
Loki::Private::ConversionHelperだけど
MCD本39ページ解説の通りになってるけど
型"U"がコピーコンストラクタをprivateにしてたらコンパイルエラーだよね?

static Small Test(U);
じゃなくて
static Small Test(U&);
にすればいいと思うんだけどダメなのかな?



480 名前: デフォルトの名無しさん 投稿日: 03/01/12 12:13
>>479
それだと二重参照が起きたりしない?


481 名前: デフォルトの名無しさん 投稿日: 03/01/12 12:25
まあちゃんとしたのが使いたければboost/type_traits/is_converson.hpp
を使えってことなんだろうね。Lokiはそもそも教育用のサンプルなんだし。
それにしてもboostのソースはLokiよりも読むのにえらい時間がかかるなあ。


482 名前: デフォルトの名無しさん 投稿日: 03/01/12 12:27
s/converson/convertible/
二重に間違えてスマソ


483 名前: デフォルトの名無しさん 投稿日: 03/01/12 14:54
>>471
std::setのメンバ関数のfindは使えないけど、こんなのはどうだ。

struct person {
int id;
std::string name;
person(int i, char* str) : id(i), name(str) {}
bool operator==(int i) const {
return id == i;
}
};

// 中略

int main()
{
PersonSet ps;
ps.insert(person(1, "def"));
ps.insert(person(5, "abc"));
PersonSet::iterator it = std::find(ps.begin(), ps.end(), 5);
std::cout << it->id << ' ' << it->name << std::endl;
}


484 名前: デフォルトの名無しさん 投稿日: 03/01/12 14:58
あるいは、==演算子をオーバーロードするのが気持ち悪ければ、次のように。

struct person {
int id;
std::string name;
person(int i, char* str) : id(i), name(str) {}
};

class cmp {
int key;
public:
cmp(int i) : key(i) {}
bool operator()(person& p) const {
return key == p.id;
}
};

// 中略

int main()
{
PersonSet ps;
ps.insert(person(1, "def"));
ps.insert(person(5, "abc"));
PersonSet::iterator it = std::find_if(ps.begin(), ps.end(), cmp(5));
std::cout << it->id << ' ' << it->name << std::endl;
}


485 名前: デフォルトの名無しさん 投稿日: 03/01/12 15:49
>>483
それはアホやろ。


486 名前: デフォルトの名無しさん 投稿日: 03/01/12 15:53
>>485
やっぱり?(^_^;)


487 名前: デフォルトの名無しさん 投稿日: 03/01/12 19:01
VC6だとunsigned char* から char* に変換できませんとエラーが
でるんだが、VC++.NETだとエラーにならない。...バグなのかなぁ?

#include<sstream>
#include<vector>
using namespace std;
struct a
{
stringstream _Base;
template<typename _Alloc> void operator>>(std::basic_string<unsigned char, std::char_traits<unsigned char>, _Alloc>& str)
{
std::basic_string<char, std::char_traits<char>,_Alloc > strbuf;
( (*this) >> strbuf);//////ここ
str= reinterpret_cast<const unsigned char*>(strbuf.c_str());
}
template<typename _Alloc> void operator>>(std::basic_string<char, std::char_traits<char>, _Alloc>& str)
{
_Base >> str;
}
};

int main()
{
a A;
basic_string<unsigned char> str;
A >> str;
}


488 名前: デフォルトの名無しさん 投稿日: 03/01/12 19:09
>>587
gcc3.2.1だとエラーが多くてコンパイルできない。何とかしてくれ。


489 名前: C++厨 投稿日: 03/01/12 19:22
このスレカコイイ!


490 名前: デフォルトの名無しさん 投稿日: 03/01/12 19:33
#include<sstream>
#include<vector>
class A
{
public:
std::stringstream _Base;
template<typename _Alloc> void operator>>(std::basic_string<unsigned char, std::char_traits<unsigned char>, _Alloc>& str)
{
std::basic_string<char, std::char_traits<char>,_Alloc > strbuf;
( *this >> strbuf);//////ここ
str.assign(reinterpret_cast<const unsigned char*>(strbuf.c_str()));
}
template<typename _Alloc> void operator>>(std::basic_string<char, std::char_traits<char>, _Alloc>& str)
{
_Base >> str;
}
};

int main()
{
A a;
std::basic_string<unsigned char> str;
a >> str;//(1)NG ->エラー
std::string str2;
a >> str2;//(2)OK
}


491 名前: デフォルトの名無しさん 投稿日: 03/01/12 20:11
boostのsmart_ptr全般で、boolへの暗黙の型変換をするとき、
なんでこんなヘンなことやってるの?
operator bool()ではいけないんですか?

// implicit conversion to "bool"
typedef T * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{
 return ptr == 0? 0: &this_type::get;
}


492 名前: デフォルトの名無しさん 投稿日: 03/01/12 20:29
いや、最近のニュー速は本当に良くなってきたと思うよ。
ニュース速報板だからね。


493 名前: デフォルトの名無しさん 投稿日: 03/01/12 20:33
・・・横槍。

削除依頼を内容証明以外の方法で行っても有効ですが、条理が根拠ではありません。
意思表示の一般原則であり自明のことです。
免責の対象にはならないから安心してください。


494 名前: デフォルトの名無しさん 投稿日: 03/01/12 20:40
>>491
smart_ptr p;
int x = p + 1;
こんなクソコード書く奴にコンパイルエラーを叩きつけるため。


495 名前: 491 投稿日: 03/01/12 20:42
うーん。
http://lists.boost.org/MailArchives/boost/msg38117.php
あたりでやりとりされてるけど、ようわからん。
それによると・・・
・operator bool()ではintへの暗黙の型変換をするからダメ。->なんで?
・private:operator int()してもダメ。->なんで?




496 名前: デフォルトの名無しさん 投稿日: 03/01/12 20:42
gannbattekudasai


497 名前: 491 投稿日: 03/01/12 20:47
>>494 おっと、入れ違い。
そうか、intになってしまったら*+-/なんかの演算子が許されるのか・・・


498 名前: デフォルトの名無しさん 投稿日: 03/01/13 01:17
今改めてそのスレッド追うの面倒なので記憶に頼って書くけど、
> ・private:operator int()してもダメ。->なんで?
これは結構いいんでない?という結論になったのでなかったか。
 smart_ptr p;
 cout << p << endl;
がコンパイル通ってbool値を表示してしまうという問題はあるけれど。


499 名前: デフォルトの名無しさん 投稿日: 03/01/13 01:23
こんな簡単なコードが通りません。

std::basic_string<unsigned char> str;
const unsigned char* p = (const unsigned char*)"abc";
str = p; //もしくはstr.assign(p);

どおして通らないのかどなたかわかりません?


500 名前: デフォルトの名無しさん 投稿日: 03/01/13 03:31
unsignedは何か意味があるの?


501 名前: デフォルトの名無しさん 投稿日: 03/01/13 03:41
>>500
>>487>>490のリストをgccでコンパイルするとエラーになるので、エラーが再現
する最小のプログラムを探していったら>>499になりました。

単にstd::basic_stringをunsigned charで型特定しただけなのになぜエラーが
出るんでしょうね?


502 名前: デフォルトの名無しさん 投稿日: 03/01/13 03:50
bits/basic_string.h見てもよく分からんね。
なにか基本的なことがわかってないっぽい<自分


503 名前: デフォルトの名無しさん 投稿日: 03/01/13 03:51
だから、どんなエラーがでるんだよ。


504 名前: デフォルトの名無しさん 投稿日: 03/01/13 03:54
>>504
リンクエラー


505 名前: デフォルトの名無しさん 投稿日: 03/01/13 03:57
ホゥ、世の中には、「リンクエラー」以上の情報を
報告しようとしない変態リンカが存在するのか、、、
デバッグもさぞ大変な事だな、、


506 名前: デフォルトの名無しさん 投稿日: 03/01/13 04:02
undefined reference to `std::char_traits<unsigned char>::length(unsigned char const*)'
undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)'
undefined reference to `std::char_traits<unsigned char>::move(unsigned char*, unsigned char const*, unsigned)'
undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)'
undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)'
undefined reference to `std::char_traits<unsigned char>::move(unsigned char*, unsigned char const*, unsigned)'
undefined reference to `std::char_traits<unsigned char>::copy(unsigned char*, unsigned char const*, unsigned)'
です


507 名前: デフォルトの名無しさん 投稿日: 03/01/13 04:14
$ g++ -v
gcc version 2.95.2 19991024 (release)
では、ちゃんとコンパイル・リンクできたが。


508 名前: デフォルトの名無しさん 投稿日: 03/01/13 04:15
>>506
書いてあるとおりだと思うが。std::char_traits<>::xxx() ってテンプレート
関数を unsigned char で特殊化したものを用意しろ、ってことだろ。


509 名前: デフォルトの名無しさん 投稿日: 03/01/13 04:46
これってgcc3.xのbits/char_traits.hバグ?
それともSTLの仕様?
バグならバグレポート書きたいのだけど。


510 名前: デフォルトの名無しさん 投稿日: 03/01/13 05:17
> バグならバグレポート書きたいのだけど。
そのレベルの人間は、規格書をチェックでしょう。


511 名前: デフォルトの名無しさん 投稿日: 03/01/13 05:23
http://www.cuj.com/experts/1911/reeves.htm?topic=experts
ここを見る限りじゃどうもバグじゃないっぽい。
bits/char_traits.hの中を見れば<char>と<wchar_t>しか処理が書かれて
なくて、それ以外の型を処理の書かれてないデフォルトで
拾うようになっている。ということはunsigned char、signed charは
使うなっていう暗黙のメッセージなのかな、これは?

http://www.bohyoh.com/CandCPP/FAQ/FAQ00001.html
ただここに書かれているように"char"の符号の有無は処理系依存なんだよねえ。
この辺はどうするつもりなんだろう。gcc以外のコンパイラなど使うなっていう意味かな??w


512 名前: デフォルトの名無しさん 投稿日: 03/01/13 17:42
>>508-511
499です。
charとwcahr_tで型特定されているのは、多分効率を重視するためでしょうね。
その反面、basic_stringで独自の型を用意しようとすると、assign()などのメンバ
を自分で用意してやらないといけなくなったと。

これで、悩まずに済むようになりました。ありがとうございました。


513 名前: デフォルトの名無しさん 投稿日: 03/01/13 17:57
Borland-C++5.6.2では、basic_stringにunsigned charを指定してもエラー
にはなりません。それは、多分型特定してないからですね。
Include\stl\string.hを見てもそれらしい型特定はありません。

Borland-C++5.6.2はSTLportなので、確実な事は言えませんがgccでも
STLportを導入すればunsigned charの問題は回避できるような気がします。


514 名前: 山崎渉 投稿日: 03/01/13 18:26
(^^)


515 名前: デフォルトの名無しさん 投稿日: 03/01/13 22:14
こんなアホサイトに人生振り回される奴もどうかしてるがな



516 名前: 質問 投稿日: 03/01/15 12:45
こういうのって loki にはないですか?

template<int v> struct Int2Type{
public: enum { Value = v };
};

template<typename T1, typename T2, bool isT1GreaterThanT2> struct SizeCompareRaw {
typedef int Greater;
typedef int Lesser;
};

template<typename T1, typename T2> struct SizeCompareRaw<T1, T2, true> {
typedef T1 Greater;
typedef T2 Lesser;
};
template<typename T1, typename T2> struct SizeCompareRaw<T1, T2, false> {
typedef T2 Greater;
typedef T1 Lesser;
};

template<typename T1, typename T2> struct SizeCompare{
typedef SizeCompareRaw<T1, T2, Int2Type<(sizeof(T1) > sizeof(T2))>::Value >::Greater Greater;
typedef SizeCompareRaw<T1, T2, Int2Type<(sizeof(T1) > sizeof(T2))>::Value >::Lesser Lesser;
};

typedef SizeCompare<SizeCompare<int, char>::Greater, long long>::Greater GreatestType;

もしあったら、もっと単純できれいな実装でしょうか?


517 名前: デフォルトの名無しさん 投稿日: 03/01/15 13:19
>>516
何がしたいのか、日本語で書いてみないか?


518 名前: デフォルトの名無しさん 投稿日: 03/01/15 14:29
>>516
> loki にはないですか?
Loki は小さいから自分で調べてみるとよろし。
少なくとも俺の記憶では、そのものズバリは無いんじゃないかと…

> もっと単純
Int2Type 使わなくともいいと思う。
あと、1番上の SizeCompareRaw の定義はいらない。

Loki::Select を再利用するとか…
template<class T, class U> Large {
  typedef Select<sizeof(T) > sizeof(U), T, U>::Result Result;
};


519 名前: 山崎渉 投稿日: 03/01/15 17:52
(^^)


520 名前: デフォルトの名無しさん 投稿日: 03/01/15 18:34
式templateとかで静的な値を得るのに
特別な技法を使うんじゃなく、
構文が使えたら便利だよね。
(回りくどい表現になりがちだから。)


521 名前: 516 投稿日: 03/01/16 01:41
みなさんレスありがとうございます。
>>517
サイズの大きい方の型を得たかったのです。

>>518
上のソースが、Modern C++ を読んでから自分ではじめて考えた
generative 風のコードなので
(モダ++に)解説されている範囲外は、ソース見ても、まださっぱりなんですよ^^;
(見ても求めているものかどうかよくわからないんです、試せばいいのですが…^^; 本格的に g++ に乗り換えかな…)
これから少しずつ精進していこうと思います。
Int2Type を使わないで書くとどういう感じなのでしょう?
さっぱり思い当たらないのですが、ヒントだけでもいただけないでしょうか?

>>520
host-policy とかも、文法レベルでサポートしてほしいですよね。
loki を見てると、ライブラリでやる範疇をそろそろ超えているような気が…
(いい意味で捕らえると C++ の(これまでの)限界を打ち破る力だと思うのですが…)


522 名前: デフォルトの名無しさん 投稿日: 03/01/16 08:55
>>521
Lokiが使えるなら、ヒントどころか答えが>>518に書いてあると思うんだが。


523 名前: デフォルトの名無しさん 投稿日: 03/01/16 12:47
教えてください。

tupleのvectorをtupleの第1要素でソートしたいときどうしたらいいんでしょう。

typedef boost::tuple<int, double> Tuple;

std::vector<Tuple> data;
// data.push_back(boost::make_tuple(1, 1.0)); ....

std::sort(data.begin(), data.end(),
boost::bind(
std::less<int>(),
boost::bind(boost::mem_fn(&Tuple::get<0>, _1),
boost::bind(boost::mem_fn(&Tuple::get<0>, _2)
));

これだとコンパイル通りませんでした。
(BCB6で「コンパイラ内部のエラー」)

なんか間違ってるでしょうか。
それか、こういう場合もっと簡単な方法があるんでしょうか?


524 名前: デフォルトの名無しさん 投稿日: 03/01/16 19:45
何気に難しいな、どうやるんだろ


525 名前: デフォルトの名無しさん 投稿日: 03/01/16 20:58
力ずくで良いなら

struct CompByTuple1st
{
  bool operator()(const Tuple& t1, const Tuple& t2)
  {
    return t1.get_head() < t2.get_head();
  }
};

を比較用の関数オブジェクトとして sort に渡す、かねぇ。汎用性ゼロ
だが。


526 名前: デフォルトの名無しさん 投稿日: 03/01/17 02:02
>>523
それであってる (gccなら通る) 。…が、その場合 mem_fn はなくてもOK。
BCBでまともに boost::bind を動かすのはあきらめた方が無難ではないかと。


527 名前: デフォルトの名無しさん 投稿日: 03/01/17 10:33
皆さんありがとうございました。BCBでbind系が使えるようになる日を待ちます。
とりあえず、比較オブジェクトをtemplateにして

template <typename T, int I>
struct CompareByNth
{
bool operator()(const T & a, const T & b) const
{
return a.get<I>() < b.get<I>();
}
};

で逃げることにしました。これにstd::lessを簡単に渡せればいいんですけど…


528 名前: デフォルトの名無しさん 投稿日: 03/01/17 14:54
>>526
gccで通った?俺はg++3.2.1で試してみたが、
C:/MinGW/Learn/boost/tuple.cpp:18: no matching function for call to `mem_fn(
<unknown type>, boost::arg<1>&)'

C:/MinGW/Learn/boost/tuple.cpp:19: no matching function for call to `mem_fn(
<unknown type>, boost::arg<2>&)'
C:/MinGW/Learn/boost/tuple.cpp:21: parse error before `;' token
なんてエラーが出やがる。


529 名前: デフォルトの名無しさん 投稿日: 03/01/17 22:34
g++も駄目か


530 名前: デフォルトの名無しさん 投稿日: 03/01/18 00:06
>>528>>529
boost::mem_fnを取ったらg++で通ったよ。


531 名前: 526 投稿日: 03/01/18 01:21
>>528
あーほんとだ。523のをコピペじゃなくて書き写したんで、微妙に
違うコードをコンパイルしてたわ。
sort( data.begin(), data.end(),
 bind( less<int>(),
  bind( mem_fn(&Tuple::get<0>), _1),
  bind( mem_fn(&Tuple::get<0>), _2) ));
//mem_fnは無くてOK。


532 名前: デフォルトの名無しさん 投稿日: 03/01/19 15:53
std::accumulateを使ってプログラムを書いてみたのですが、何かこうもっと
スマートに書けないものでしょうか?

struct A {
virtual int func() {
return 1;
}
};

struct B : public A {
int func() {
return 2;
}
};

int AddA(int i, A* a)
{
return i + a->func();
}


533 名前: デフォルトの名無しさん 投稿日: 03/01/19 15:53
int main()
{
std::vector<A*> a;
const int maxi = 100000;

for (int i = 0; i < maxi; i++)
if (std::rand() % 2)
a.push_back(new A);
else
a.push_back(new B);

int i;
std::accumulate(a.begin(), a.end(), 0, AddA);
std::cout << i << std::endl;
}


534 名前: デフォルトの名無しさん 投稿日: 03/01/19 16:07
>>533
back_inserter と generator 使うと、もっとうまく書けそうな予感。


535 名前: デフォルトの名無しさん 投稿日: 03/01/19 16:18
うーんこれでもまだ不格好だ・・・・

struct Add {
int value;
Add(int i) : value(i) {}
void operator()(A* a) {
value += a->func();
}
};

int main()
{
std::vector<A*> a;
const int maxi = 100000;

for (int i = 0; i < maxi; i++)
if (std::rand() % 2)
a.push_back(new A);
else
a.push_back(new B);

int i;
i = std::for_each(a.begin(), a.end(), Add(0)).value;
std::cout << i << std::endl;
}


536 名前: デフォルトの名無しさん 投稿日: 03/01/19 16:18
>>534
back_inserterを使うという事は、他のvectorに値を入れるという事でしょうか?


537 名前: デフォルトの名無しさん 投稿日: 03/01/19 16:34
できました。もう一個vectorを使ってやってみました。こんな感じでしょうか?

int main()
{
std::vector<A*> a;
std::vector<int> b;
const int maxi = 100000;

for (int i = 0; i < maxi; i++)
if (std::rand() % 2)
a.push_back(new A);
else
a.push_back(new B);

std::transform(a.begin(), a.end(), std::back_inserter(b), std::mem_fun(&A::func));

int i;
i = std::accumulate(b.begin(), b.end(), 0);
std::cout << i << std::endl;
}


538 名前: デフォルトの名無しさん 投稿日: 03/01/19 16:38
さらにアルゴリズムを使ってみました。私にはこの辺が限界です。

inline A* gen()
{
return (std::rand() % 2) ? new A : new B;
}

int main()
{
std::vector<A*> a;
std::vector<int> b;
const int maxi = 100000;

std:generate_n(std::back_inserter(a), maxi, gen);
std::transform(a.begin(), a.end(), std::back_inserter(b), std::mem_fun(&A::func));

int i;
i = std::accumulate(b.begin(), b.end(), 0);
std::cout << i << std::endl;
}


539 名前: デフォルトの名無しさん 投稿日: 03/01/19 16:54
もう一個vectorなんて、許さん。

#include <boost/iterator_adaptors.hpp>
int accumulate( const std::vector< A* >& v )
{
    std::mem_fun_t< int , A > func( &A::func );
    return std::accumulate(   boost::make_transform_iterator( v.begin() , func )
                            , boost::make_transform_iterator( v.end() , func )
                            , 0 );
}



540 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:04
gcc2.95を使ってるんだけど、ちょっと複雑なテンプレートで
すぐにInternal compiler errorを吐きやがります。
VC6は食います。

そんなもんですかね。


541 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:08
>>539
すげー!こんなコードが書けるのか。
やっぱりSTLやboostは奥が深いですねえ。


542 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:10
>>540
VCも使ってるって事は、gccはcygwinかMinGW?


543 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:21
>>542
YES YES YES
gcc3,VC7ではもちろんとおります


544 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:23
>>543
gcc2.95.2にこだわる理由は何?
もしかして仕事で使っているとか?


545 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:31
>>538
std::vector<A*> a を generate_n で作るまでは OK として、その後は

  std::accumulate(v.begin(), v.end(), 0,
        boost::compose_f_gx_hy(
          std::plus<int>(),
          std::identity<int>(),
          std::mem_fun(&A::func)
        ));

ってな感じでどう?


546 名前: 545 投稿日: 03/01/19 17:33
>>539
うまいな。そっちの方が見やすいかもしれん。

>>540
template 使いたいなら gcc 3 系列に移行しましょう。

…俺も仕事でいまだに gcc 2.96 使ってるけど、早く捨てたい。


547 名前: 543 投稿日: 03/01/19 17:41
趣味だったらVC7/GCC3にするって。
仕事なんでVC6/GCC2.95を使わざるをえません。

あれからいろいろいじったけど、
どうやってもgcc2.95で通らないんだな。

vc6は、使うものしか処理しないって感じだねえ。
gcc2.95は、使おうが使うまいが、ある程度処理するみたい。
落ちてるところは実際には使われない部分だったりするからナントモ。


548 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:43
>>545
std::identityってのは初めて見ました。ここの文脈ではint()とは書けないから
必要なんですね。標準C++には無いようですが、STLportには幸いにも装備
されていました。


549 名前: デフォルトの名無しさん 投稿日: 03/01/19 17:47
ところでg++3.2.1でstd::identityがエラーが出るのですが、boostには
これの代用になる物がありますか?


550 名前: デフォルトの名無しさん 投稿日: 03/01/19 18:20
>>549
簡単なものだから、自分で書いちゃっても。
これは要するに

 f(x) = x

となるような恒等変換をする関数オブジェクト。

namespace std {
  template <typename T>
  struct identity : public unary_function<T, T>
  {
    T& operator()(T& x) const { return x; }
    const T& operator()(const T& x) const { return x; }
  };
}



551 名前: デフォルトの名無しさん 投稿日: 03/01/19 18:28
>>550
なるほど、関数オブジェクト化すればよかったのですね。
ありがとうございます。


552 名前: デフォルトの名無しさん 投稿日: 03/01/19 18:51
template<bool Val>
struct A{
   template<class T> struct B{};
};
template<class T1,class T2>
struct C{
   typedef A<sizeof(T1)==sizeof(T2)>::B<T1> type;
};
main(){
   A<sizeof(int)==sizeof(int)>::B<int> val1; // ここはエラーにならない
   C<int,int>::type val2; // ここでエラー
}
これって文法的にはどうなんでしょうか?

VC7とDigital Mars C++では通るのですが、
去年の夏ごろのmingwではコンパイラ内部エラーになり、
冬に出たmingwでは内部エラーにはならないもののコンパイルできないのです。


553 名前: デフォルトの名無しさん 投稿日: 03/01/19 21:57
vectorクラスにpush_backしたらポインタがふっとんでがびーん



554 名前: 543 投稿日: 03/01/19 23:20
ようやく最小限のコードになったよ・・・

-----
// gcc2.95(cygwin)でinternal compiler error

template<typename T>
struct A {
  T* pT;
};

//template<typename V>
struct B {
  template<typename T>
  struct C : public A<T> {
    void func(T* pT) {
      return;
    }
  };
};
-----

中央のコメントアウトしたのを外すと通し、使える。
ひょっとして外出?


555 名前: デフォルトの名無しさん 投稿日: 03/01/19 23:26
>>554
手元の処理系で試してみたけど

× gcc version 2.95.4 20020320 [FreeBSD]
○ gcc version 2.96-ee-001003-1
○ gcc version 3.2 (mingw special 20020817-1)

ってことで gcc 2.96 で修正済みのバグと思われ。


556 名前: デフォルトの名無しさん 投稿日: 03/01/19 23:31
>>555
検証サンクス。gcc2.95そのもののバグなのね。
とりあえずB<void>でworkaroundしときます。

これでようやくVC6と合わせられる・・・


557 名前: デフォルトの名無しさん 投稿日: 03/01/20 16:08
stlのmapコンテナで
map<string,int> WD;
としている時に
mapのsecondの値(int)の大小を比較して大きい順にソートするよい方法って
ないですか?
最終的にはそのソートされたfirst(string)を順番に表示したいのですが。


558 名前: デフォルトの名無しさん 投稿日: 03/01/20 16:13
>>557
firstとsecondを逆にして他のmapに挿入し直す。


559 名前: デフォルトの名無しさん 投稿日: 03/01/20 16:24
>>557
ありがとうございます。
intをキー値に持つマップに格納してみます。


560 名前: デフォルトの名無しさん 投稿日: 03/01/20 18:04
STLportのstd::mapとstd::hash_mapの速度がどれくらい違うか実験してみました。
コンパイラはBorland-C++5.6.2です。

hash_map insert(10) = 107
map insert (10) = 114
hash_map lookup(10) = 48
map lookup (10) = 29
hash_map insert(100) = 486
map insert (100) = 708
hash_map lookup(100) = 289
map lookup (100) = 277
hash_map insert(1000) = 5395
map insert (1000) = 7743
hash_map lookup(1000) = 2593
map lookup (1000) = 3586
hash_map insert(10000) = 54202
map insert (10000) = 93014
hash_map lookup(10000) = 28221
map lookup (10000) = 54862
hash_map insert(100000) = 839600
map insert (100000) = 1476372
hash_map lookup(100000) = 335070
map lookup (100000) = 1084240
hash_map insert(500000) = 3934177
map insert (500000) = 9722710
hash_map lookup(500000) = 1835211
map lookup (500000) = 7610511

予想以上の差に驚いています。要素の数が増大すればする程差が開いて
行きますね。


561 名前: デフォルトの名無しさん 投稿日: 03/01/20 22:11
boost::function1<bool,int,int> とか boost::function1<int,int,int> とかを
まとめてvectorとかに入れたいんだけど、どうすればいいかな?



562 名前: デフォルトの名無しさん 投稿日: 03/01/20 22:13
  ∋8ノノハ.∩
   川o・-・)ノ <先生!こんなのがありました!
__/ /    /   
\(_ノ ̄ ̄ ̄\
||ヽ|| ̄ ̄ ̄ ̄||
 ...|| ̄ ̄ ̄ ̄||
http://saitama.gasuki.com/hiroyuki/


563 名前: デフォルトの名無しさん 投稿日: 03/01/21 10:35
>>562
金融のバナーばっかり



564 名前: 557 投稿日: 03/01/21 11:44
>>558さんの言うとおりに<string, int>の新しいマップ関数を定義して
firstとsecondを入れ替えてみたのですがこれを出力すると
intの数値が同じものはstring部がすべて表示できませんでした。
このように数値が重複しているものでも別々に出力するにはどうすれば
いいのでしょうか?


565 名前: デフォルトの名無しさん 投稿日: 03/01/21 11:54
>>564
multimap


566 名前: デフォルトの名無しさん 投稿日: 03/01/21 13:52
>564
そのくらいは自分で分かるようになりなよ…。
そもそも連想配列が分かってないんじゃ?


567 名前: デフォルトの名無しさん 投稿日: 03/01/21 18:23
>>564

int main()
{
std::map<std::string, int> si;

si["abc"] = 1;
si["def"] = 1;
si["ghi"] = 2;

std::multimap<int, std::string> is;
std::map<std::string, int>::iterator sii;

for (sii = si.begin(); sii != si.end(); ++sii)
is.insert(std::make_pair(sii->second, sii->first));

std::multimap<int, std::string>::iterator isi;
for (isi = is.begin(); isi != is.end(); ++isi)
std::cout << isi->first << ' ' << isi->second << std::endl;
}


568 名前: デフォルトの名無しさん 投稿日: 03/01/23 00:03
gcc (GCC) 3.2 20020927 (prerelease) on Cygwin(1.3.18-1)でコンパイル通らないんですけど何故に?
ちなみに1次元配列なら全然問題ないんスけど。教えてぷりーず。

#include <vector>
using namespace std;
int main()
{
vector<vector<int> > IntAry;
IntAry.assign(5);// 5 x 6 array
for(int i=0; i<IntAry.size(); i++) IntAry[i].assign(6);
}


569 名前: デフォルトの名無しさん 投稿日: 03/01/23 00:16
>>568
コンパイルエラーを省くなとあれほど・・・・


570 名前: デフォルトの名無しさん 投稿日: 03/01/23 00:20
>>568
vector.assign(int)というメンバ関数はないっス・・・・・・


571 名前: デフォルトの名無しさん 投稿日: 03/01/23 00:38
>>568
この場合はresize()では。


572 名前: デフォルトの名無しさん 投稿日: 03/01/23 00:45
>>568
vector<vector<int> > IntAry(5, vector<int>(6, 0));


573 名前: デフォルトの名無しさん 投稿日: 03/01/23 05:28
getch( )の( )って何のタメにあるの?
中に何か入るの?


574 名前: デフォルトの名無しさん 投稿日: 03/01/23 05:31
>>537
受け取るための袋だろ?


575 名前: デフォルトの名無しさん 投稿日: 03/01/23 08:06
おまいら、アホみたいに頭いいな。感動した。


576 名前: デフォルトの名無しさん 投稿日: 03/01/23 12:42
>>573
関数のプロトタイプないし呼び出しにて、「引数が何も無い」 事を示している。
括弧をつけないと、関数のプロトタイプないし呼び出しではなく関数へのポインタを得る事になる。


577 名前: 山崎渉 投稿日: 03/01/23 20:00
(^^)


578 名前: デフォルトの名無しさん 投稿日: 03/01/23 23:16
>>570
スマソ。投稿後すぐに分かった。
>>572
何故分かるの?凄すぎ。出直し逝ってきます。


579 名前: デフォルトの名無しさん 投稿日: 03/01/23 23:18
>>578
std::vectorには、vector c(n, elem) というコンストラクタがある。
elemの要素をn個コピーして初期化する。
って書かなくてもわかるよね。


580 名前: デフォルトの名無しさん 投稿日: 03/01/24 17:33
いい加減にboostをSTLに組み込めと。


581 名前: デフォルトの名無しさん 投稿日: 03/01/24 17:43
いい加減にboostをSTLに組み込めと。


582 名前: デフォルトの名無しさん 投稿日: 03/01/24 18:12
いい加減にboostにSTLを組み込めと。


583 名前: デフォルトの名無しさん 投稿日: 03/01/24 18:32
>>580-582
標準C++の次期規格が固まる時まで無理だと思ふ。


584 名前: デフォルトの名無しさん 投稿日: 03/01/24 18:33
あっboost「に」STL「を」組み込むのか。なぜそんな事をする必要があるの?
そうなったらstdのコンテナは使わないって意味?


585 名前: デフォルトの名無しさん 投稿日: 03/01/24 18:35
>>584
>>582は完全にネタだろ。


586 名前: デフォルトの名無しさん 投稿日: 03/01/25 05:08
Loki::SmartPtrのOwnershipパラメータ用Lokiが定義してるポリシーのうち、
Loki::RefCountedMTだけテンプレートパラメータの数が違う気がするんですが、
これでいいんですか?
gccだとコンパイル通りませんが。

int main(void){
  Loki::SmartPtr<int, Loki::RefCountedMT> p;
  return 0;
}

過去ログ一応見ましたが、がいしゅつだったらご免なさい。


587 名前: デフォルトの名無しさん 投稿日: 03/01/26 00:05
今、boost の weak_ptr のソースを読んでいて、
(文法レベルで)ちょっとわからない事があったのですが、
コンストラクタの引数の

template<typename Y>
weak_ptr(weak_ptr<Y> const & r)

という書き方、これは一体何を表しているのでしょうか?
生のポインタなら Y* const はわかるのですが、それって対応するのは
weak_ptr<const Y> ですよね?
ポインタ自体が const なら const weak_ptr<Y> ですよね?
weak_ptr<Y> const& っていうのは何を表しているんでしょうか?


588 名前: デフォルトの名無しさん 投稿日: 03/01/26 00:06
>>587
const AAA &

AAA const &
は同じ意味。


589 名前: 587 投稿日: 03/01/26 00:12
>>588
ななななんと!知りませんでした…。そんな書き方ができるとは…。
ありがとうございました。読みづらい…鬱だ…。


590 名前: デフォルトの名無しさん 投稿日: 03/01/26 00:27
>>589
↓こんな話があった。
http://pc3.2ch.net/test/read.cgi/tech/1002252975/594-626


591 名前: 587 投稿日: 03/01/26 00:50
質問続きでスミマセン。

VC++6.0 で boost::mem_fn を自作スマートポインタに適用しようとしたら

C:\Program Files\Microsoft Visual Studio\VC98\include\xmemory(34) : error C2660: 'new' : 関数が不正な 2 個の実引数をともなって呼び出されました。
C:\Program Files\Microsoft Visual Studio\VC98\include\xmemory(66) : コンパイルされたクラスのテンプレートのインスタンス化 'void __cdecl std::_Construct(MyPtr<PointeeType> *,const MyPtr<PointeeType> &)' の参照を確認してください

みたいなエラーになりました。何がいけないか以上の情報でわかる人いますか?
ちなみに同じ状況で自作スマートポインタを boost::shared_ptr に変えると
コンパイル通るのです。

>>590
激しく鬱ですね…。ポインタが全て Ptr<PointeeType> みたいな書式になって
配列を int[] num; みたいに書ければ const が全て直後の型に掛かる。で統一できるのに…。


592 名前: デフォルトの名無しさん 投稿日: 03/01/26 09:50
>>591
boost::mem_fn 側ではnewもstd::allocatorも一つも使っていないようだが…。
そのエラーは他の場所が原因に見える。あと、mem_fn を使うには
namespace boost {
  template<typename T> T* get_pointer( const T& p ) { return &*p; }
}
が必要だが、書いてる?

>>589
boost coding guildline。らしい。
http://groups.yahoo.com/group/boost/files/coding_guidelines.html#decl_initialization


593 名前: デフォルトの名無しさん 投稿日: 03/01/26 10:52
VisualStdio6.0を使っていますがexportが使えないようなのですがそれに代わるものは何かあるのでしょうか?



594 名前: デフォルトの名無しさん 投稿日: 03/01/26 11:22
export が使える処理系って、comeau くらい? って、使ったことないけど。
で、プログラム内でのそのテンプレートの使い方が限られているなら
明示的インスタンス生成ですな。


595 名前: デフォルトの名無しさん 投稿日: 03/01/26 11:46
>>592
そのガイドラインの評価ってどうなってんの?


596 名前: デフォルトの名無しさん 投稿日: 03/01/26 13:12
重複チェックをする場合としない場合の両方に対応する必要があるプログラムを作成しています。
そこでSTLのsetとmultisetを使おうと思って以下のように書いたんですが、
ソースのいたるところでif(cyofukuOK)の分岐だらけになってしまってます。
もっといい方法ないでしょうか?


set<AnsiString> setContainer
multiset<AnsiString> multiContainer
//以下略


if(cyofukuOK)
multiContainer.insert(tmp);
else
setContainer.insert(tmp);



597 名前: デフォルトの名無しさん 投稿日: 03/01/26 13:18
>>596
multisetを操作するラッパーを作ればいいんじゃねーの?


598 名前: デフォルトの名無しさん 投稿日: 03/01/26 13:22
>>596
std::set, std::multiset を直にコードに埋めずに、

1) std::set を保持し、それを操作するクラス。
2) std::multiset を保持し、それを操作するクラス。

と二つに分けてしまう。

Set* pSet;
if (cyofukuOK)
  pMap = new MultiSet();
else
  pMap = new UniqueSet();

struct Set {
  virtual void insert(AnsiString) = 0;
  ...
};

class UniqueSet : public Set {
  std::set<AnsiString> container_;
public:
  void insert(AnsiString s) { container_.insert(s); }
};

class MultiSet : public Set {
  std::set<AnsiString> container_;
public:
  void insert(AnsiString s) { container_.insert(s); }
};


599 名前: デフォルトの名無しさん 投稿日: 03/01/26 14:31
596です。
598さん、ありがとうございます。
早速やってみました。
コンテナに保持するまではうまくいったのですが、
iteratorはどうやって保持すればいいんでしょうか?
以下のようにすると特化パラメータを指定しろというエラーメッセージが出るのですが、よくわかりません。
forで使うのでbegin(),end()も必要なんでしょうかね?やはり・・

struct mySet {
virtual void insert(AnsiString) = 0;
virtual iterator getiterator(void) = 0;
};
class UniqueSet : public mySet {
std::set<AnsiString> container_;
std::set<AnsiString>::iterator itrator_;
public:
void insert(AnsiString s) { container_.insert(s); }
iterator getiterator(void) { return itrator_; }
};

class MultiSet : public mySet {
std::multiset<AnsiString> container_;
std::multiset<AnsiString>::iterator itrator_;
public:
void insert(AnsiString s) { container_.insert(s); }
iterator getiterator(void) { return itrator_; }
};


600 名前: デフォルトの名無しさん 投稿日: 03/01/26 14:32
596です。
ちなみに現状はこんな感じです。
typedef set<AnsiString> SetContainer;
typedef SetContainer::iterator SetIterator;
SetContainer Container
;
if (cyofukuOK)
{
for(SetIterator it=Container.begin();it!=Container.end();++it)
TRichEdit1->Lines->Add(*it);
{
else
{
以下略
}



601 名前: 591 投稿日: 03/01/26 14:58
おはよう(?)ございます。

>>592
か、書いてませんでした。下記のような感じのオーバーロードでいいのでしょうか?
namespace boost
{
 template <typename T>
 T* get_pointer(const MyNamespace::MyPtr<T>& smartPtr)
 {
  return &(*smartPtr);
 }
}

ちなみにこれを書いてもエラーメッセージは何も変わりませんでした。
よろしくお願いします。


602 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:10
>>599
> 以下のようにすると特化パラメータを指定しろというエラーメッセージが出るのですが、
そりゃ

> iterator getiterator(void) { return itrator_; }
ここの戻り値の型である iterator ってのが、テンプレート型だからでしょ。クラス定義
の中に

typedef std::set<AnsiString>::iterator iterator;

とでも追加しとかんと。


603 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:11
ちょっと質問。
vector<T> vec; が格納している要素列の先頭アドレスを得るのに
&vec[0] とやると思うんだけど、この操作は、vec.empty() == true
の時も有効でしょうか。


604 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:16
>>603 だめだろ。


605 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:22
>>604
&vec[0] に「書き込む」のはダメだが、&vec[0] を取得するのは問題ないと思うぞ。


606 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:22
>>602
あなたひどいひとね。


607 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:32
>>605
その式の値をどう使うつもりだ?


608 名前: 605 投稿日: 03/01/26 15:32
ごめん、やっぱりダメかも。operator[] ではなく at 使うと例外投げるのが仕様だし。


609 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:35
>>607
イテレータ同士の比較とか、C 関数に渡す場合には使えるよね。

/* 要素数 num の int 配列を処理する */
extern "C" void foo(int *data, size_t num);

vector<int> v;
..
foo(&vec[0], vec.size());


610 名前: デフォルトの名無しさん 投稿日: 03/01/26 15:55
596です
解決しました。
思いっきり勘違いしてました。最終的に以下のようになりました。
ありがとうございました。
//.h
struct mySet {
virtual void insert(AnsiString&) = 0;
virtual unsigned int getSize(void) = 0;
typedef std::set<AnsiString>::iterator iterator;
virtual iterator begin(void) = 0;
virtual iterator end(void) = 0;
};
//.cpp
auto_ptr<mySet> pSet;
if(RepeatDataCheckBox->Checked)//重複なし
{
auto_ptr<UniqueSet> instance (new UniqueSet());
pSet = instance;
}
else //重複あり
{
auto_ptr<MultiSet> instance (new MultiSet());
pSet = instance;
}
pSet->insert(tmp);
typedef std::set<AnsiString>::iterator iterator;
for(iterator it = pSet->begin();it!=pSet->end();++it)
{
ed->Lines->Add(*it);
}


611 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:02
v[n]は*(v.begin()+n)と定義されていて(23.1.1 -12-)、
v.empty()のとき、v.begin()は"past-the-end"っていう値を返すことになってる(23.1 -7-)。
イテレーターiについて、*iが定義されるようなiの値を、"dereferencable"っていう
けど、"past-the-end"は"dereferencable"じゃぁない(24.1 -5-)。

ってことで、v.empty()のとき、v[0]は
"dereferencable"ではないイテレーターに operator * を適用することになるので、
未定義である。

あとから & つけたところで手遅れだと思われ。


612 名前: 605 投稿日: 03/01/26 16:05
仕様書調べてみたよ。

コンテナ a の operator[](int n) は *(a.begin() + n) と定義されているから、n = 0 のときに
*a.begin() (== *a.end()) が許されるか否かが問題。

a.end() は常に past-the-end-value (有効な要素の『次』を指す) イテレータを返し、これ


> 24.1 Iterator requirements
> 6. (前略) Values of an iterator i for which the expression *i is defined are called
> dereferenceable. The library never assumes that past-the-end values are
> dereferenceable

ということでデリファレンスしてはいけない。つまり *a.begin() という表記は NG で、
従って &a[0] も NG ってことになる。

ただし、現実には参照はコンパイラ内部ではポインタとして実装されてるから

vector<int> v;
int& n = &v[0];
int* p = &n;

とした場合でも p (n のアドレス) だけ見てる分には問題ない。ただし *p = 1 とか
int x = *p といったように、n の値を読み書きすると、一般保護違反で落ちたりメモリ
壊したりする。

……ってことかね。


613 名前: 605 投稿日: 03/01/26 16:05
一足遅かったか…


614 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:06
>>610
その場合、mySetのデストラクタにvirtualが要る。

MultiSetの実装が謎だ。なんでコンパイルとおるんだ?
絶対解決してないと思うんだが?


615 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:10
>>611
vector<T>::iterator が T* という良くある環境だと問題ないけど、STLport の
デバッグモードみたいに別の型が返ってくる(それをデリファレンスすると T
になる)だと、怒られそうな気がする。

とはいえ微妙に使いにくい仕様だな、これ。>>609 にあるような C 言語の関
数を呼ぶ場合、どうせ C 関数の方で要素数チェックして 0 なら何もしない、
ってのが普通だし、そっちにチェックを任せたいよな。


616 名前: 611 投稿日: 03/01/26 16:11
ニヤリ


617 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:12
610です
このようにしましたけど、問題ないようです。
環境はBCB5でWindowsXPです。

//重複なしのコンテナ
class UniqueSet : public mySet {
std::set<AnsiString> container_;
std::set<AnsiString>::iterator itrator_;
public:
void insert(AnsiString& s) { container_.insert(s); }
unsigned int getSize(void){ return container_.size(); }
iterator begin(void){ return container_.begin(); }
iterator end(void){ return container_.end(); }
};
//重複ありのコンテナ
class MultiSet : public mySet {
std::multiset<AnsiString> container_;
std::multiset<AnsiString>::iterator itrator_;
public:
void insert(AnsiString& s) { container_.insert(s); }
unsigned int getSize(void){ return container_.size(); }
iterator begin(void){ return container_.begin(); }
iterator end(void){ return container_.end(); }
};


618 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:21
std::set<int>::iterator f() { return std::multiset<int>::iterator(); }

gccでも↑のコードがエラーにならん。
仕様じゃ、ないよな?


619 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:25
>>615
size()==0よりもempty()を使えって話になるんじゃないか?


620 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:36
>>619
それでも

extern "C" void foo(int *data, size_t num);

に対して、これを利用する C++ 側関数は

vector<int> v;
if (!v.empty())
  foo(&v[0], v.size());

と場合分けが必要になるよね。


621 名前: デフォルトの名無しさん 投稿日: 03/01/26 16:47
>>620
↓で問題ないと思う。

inline
void foo( vector<int>& v )
{
  if(!v.empty())
    foo(&v[0],v.size());
}



622 名前: デフォルトの名無しさん 投稿日: 03/01/26 17:34
>>621
俺だったらこんな関数作って使うかな。

templat<class T>
inline T* GetFirstPointer( vector<T>& v )
{
 if(v.empty())
  return NULL;
 else
  return &v[0];
}

で、vectorが空でも&v[0]が許される実装で、
かつ効率が気になる場合は
単純に&v[0]を返すように書き換えると。


623 名前: 622 投稿日: 03/01/26 17:37

誤:templat<class T>
正:template<class T>


624 名前: デフォルトの名無しさん 投稿日: 03/01/26 17:45
>>622
>621のコードを見てなお、>622のコードを使いたくなるのって、どんなとき?


625 名前: デフォルトの名無しさん 投稿日: 03/01/26 18:06
悲しいときー


626 名前: デフォルトの名無しさん 投稿日: 03/01/26 18:35
>>624
ラッパ関数を沢山書くのが面倒な場合だろう。


627 名前: 622 投稿日: 03/01/26 18:35
>>624
fooに相当する関数が沢山あるとき。


628 名前: 622 投稿日: 03/01/26 18:54
カブった....。

あとfooが関数オブジェクトだった時や、
fooがvectorのサイズを変更しないことを示したい時にも
>622の方を使いたくなるな。


629 名前: デフォルトの名無しさん 投稿日: 03/01/26 18:55
>>627
ということは、末端のコードにGetFirstPointerがばら撒かれるわけか。
  foo(GetFirstPointer(v),v.size());
・・・うーん、あんまり賛成できないなぁ。


630 名前: 629 投稿日: 03/01/26 19:02
>>628
> fooがvectorのサイズを変更しないことを示したい時にも

あー、それあるなぁ。
やっぱりしょうがないかぁ。


631 名前: デフォルトの名無しさん 投稿日: 03/01/26 19:10
>>629
いっそ vector 継承して operator[] だけ再定義したオブジェクトを作るのも
手かもしれんな。

メンバ変数は一切増えないから、デストラクタが virtual でなくとも支障ない
しさ。


632 名前: 629 投稿日: 03/01/26 19:43
>>631
そりゃあんまりだ。


633 名前: デフォルトの名無しさん 投稿日: 03/01/26 20:10
>>611-612
でもさ、vector::operator[] って reference を返すじゃん。
てことは、&v[0] は dereference を実行してないと思うんだけど。

まあでも、v.size() == 0 の場合、要素配列を格納するための
有効なバッファがが確保されているかどうかは不明だしねぇ。
やっぱり v.empty() で切り分けるしかないかなぁ。


634 名前: デフォルトの名無しさん 投稿日: 03/01/26 20:26
>>633
> でもさ、vector::operator[] って reference を返すじゃん。
で、規格書読むと reference は「有効なオブジェクトを指さねばならない」と書いてあったり
するわけだ。

> てことは、&v[0] は dereference を実行してないと思うんだけど。
これは &(*v.begin()) と同じ意味なんだが、v.begin() が返すのが単なるポインタではない
場合には、実際に dereference が行われた上で、そのアドレスが計算されることになる。
たいていの処理系だと vector<T>::iterator は T* だから問題ないけど。


635 名前: 601 投稿日: 03/01/26 21:58
>>592
やはり別の理由でした。自作スマートポインタが、変な形式の operator new を持っていたのがいけなかったようです。
(g++ に切り替えてわかったのですが、boost::mem_fn ではなくて、その前のコンテナに突っ込むところでのエラーだったようです。)
それを取り除いて、自作ポインタ用の get_pointer を追加した所、うまくいきました。

ありがとうございました。


636 名前: 635 投稿日: 03/01/26 22:34
それと気がついた事を一つ。

get_pointer は koenig look-up があるので 名前空間 boost に入れなくても
よさそうです。


637 名前: 592 投稿日: 03/01/26 23:34
>>636
VC6って演算子じゃない関数は Koenig Lookup 出来ないんじゃなかったっけ。
最近使ってないからはっきり覚えてはいないけど…。


638 名前: デフォルトの名無しさん 投稿日: 03/01/26 23:52
昔、数値計算用に3次元や2次元ベクトルクラス(double型のみ)を自作したりしたんだけど、
最近になってテンプレート化してみたら、同じ型同士は問題なく動くけど
違う型を混ぜると下のように怒られちゃいました。
型をあわせなきゃいけないみたいだけどどうすればいいのでしょう……


borland c++ 5.5でつ

vec3<double> a
vec3< complex<double> > b,c

c=a*b;

『エラー E2094 : * 演算子が使われたがクラス Vec3<complex<double >> では Vec3<double> 型のための定義が存在しない』


639 名前: デフォルトの名無しさん 投稿日: 03/01/27 00:05
vec3<double> + vec3< complex<double> > で、あなたの書いたどのコードが
実行されると期待しているんだ?


640 名前: デフォルトの名無しさん 投稿日: 03/01/27 00:13
>>638
本質的には T から U への型変換が存在する時に、vec<T> から vec<U> への
型変換を認めたい、って話だよね。

それなら、テンプレート化したコピーコンストラクタを作る。vec3 の実装がどうなっ
てるか知らんけど、かりに vec3<T> が private 変数として T 型の配列 v_[3] を
持つと仮定すると、

template <typename T>
class vec3
{
public:
  template <typeename U>
  vec3(const vec3<U>& other)
    : v_(other.v_)
  {}
};

ってな感じ。other.v_ (U[3]型) から v_ (T[3] 型) への暗黙の型変換がある場合、
これでよろしく変換できる。


641 名前: デフォルトの名無しさん 投稿日: 03/01/27 00:55
ありがとう。何を調べればよいのかが解らないと自分一人ではどうにもならんので。

配列だと余分なアクセス入るかなと思って、ベクトルの各成分はT v[3]じゃなくてT x,y,zで実装してます。
もっと次数が高ければ当然配列にするだろうけど……あ、配列だったらSTLのvector使えばいいのか。

明日試してみます


642 名前: デフォルトの名無しさん 投稿日: 03/01/27 01:26
テンプレートクラスをstd::ostreamに出力するにはどのように定義すれば
いいのでしょうか?
コンパイルできるのですがワーニングが出ます。gcc3.2.1(MinGW)です。

template <typename T>
class A {
T value;
public:
A(double d = 0) {
value = d;
}
friend std::ostream& operator<<(std::ostream& os, const A<T>& a);
};

std::ostream& operator<<(std::ostream& os, const A<double>& a)
{
os << a.value;
return os;
}

int main()
{
A<double> a(1.23);
std::cout << a << std::endl;
}


643 名前: デフォルトの名無しさん 投稿日: 03/01/27 01:30
>>642
なんでそのコンパイラの出力をはぶきやがるんだ?


644 名前: デフォルトの名無しさん 投稿日: 03/01/27 01:37
>>643
すみません、ワーニングをコピペします。

g++.exe "C:\MinGW\Learn\Learn2\template_ostream.cpp" -o "C:\MinGW\Learn\Learn2\template_ostream.exe" -Wall -s -O3 -I"C:\mingw\include" -I"C:\mingw\include\c++" -I"C:\mingw\include" -L"C:\mingw\lib"
C:/MinGW/Learn/Learn2/template_ostream.cpp:10: warning: friend declaration `
std::ostream& operator<<(std::ostream&, const A<T>&)' declares a
non-template function
C:/MinGW/Learn/Learn2/template_ostream.cpp:10: warning: (if this is not what
you intended, make sure the function template has already been declared and
add <> after the function name here) -Wno-non-template-friend disables this
warning

Execution terminated
Compilation successful


645 名前: デフォルトの名無しさん 投稿日: 03/01/27 01:47
>>644
Friend declaration `std::ostream& operator<<(std::ostream&, const A<T>&)'
declares a non-template function.
If this is not what you intended, make sure the function template has
already been declared and add <> after the function name here.
-Wno-non-template-friend disables this warning.

・・・ってなワケだ。あとは好きなように対処しな。


646 名前: デフォルトの名無しさん 投稿日: 03/01/27 01:58
>>645
次のようにしたらコンパイル通りました。ありがとうございました。
ちなみにBCC5.6では通りませんね。

template <typename T>
class A {
T value;
public:
A(double d = 0) {
value = d;
}
friend std::ostream& operator<< <>(std::ostream& os, const A<T>& a);
};

template <typename T>
std::ostream& operator<<(std::ostream& os, const A<T>& a)
{
os << a.value;
return os;
}

int main()
{
A<double> a(1.23);
std::cout << a << std::endl;
}


647 名前: 636 投稿日: 03/01/27 16:44
>>637
なはは…うっかり忘れてました。
その間についに VC++ に別れを告げる決意を固めて、試したのは g++ 上でした。

VC++ では通らないかもしれないです。


648 名前: 638 投稿日: 03/01/28 01:03
>640
無事complex<double> とdouble間の計算が出来ますた。有難う


649 名前: デフォルトの名無しさん 投稿日: 03/01/28 03:11
テンプレート引数の型を文字列リテラルとして取り出したいんですが
どうすればいいでしょう。つまりログとりたいんです

template<typename T>
class Hoge {
public:
 Hoge() {
  Log::debug("Hoge<T>::Hoge()");
 }
};

Hoge<int> hoge;

で Hoge<int>::Hoge() と表示してほしいんですが・・・


650 名前: デフォルトの名無しさん 投稿日: 03/01/28 03:22
>>649
typeid(T).name()


651 名前: デフォルトの名無しさん 投稿日: 03/01/28 03:24
>>649
typeid(T).name()


652 名前: 651 投稿日: 03/01/28 03:25
>>650
ケコーン


653 名前: デフォルトの名無しさん 投稿日: 03/01/28 03:27
それはconst char*でして、文字列リテラルではないかと・・・
コンパイル時に Hoge<int>::Hoge になって欲しいんです・・・


654 名前: デフォルトの名無しさん 投稿日: 03/01/28 03:36
>>653
無理。
std::string でも使え。


655 名前: デフォルトの名無しさん 投稿日: 03/01/28 03:50
ガビーン
あきらめます・・・


656 名前:   投稿日: 03/01/28 17:55

"<" と ">" に挟まれた文字列を検索して格納したいのですが。
これで良いでしょうか?

{
    std::string text;
    std::string __text;
    std::string::iterator i_first;
    std::string::iterator i_last;

    i_first = __text.begin() + __text.find( "<", 0 ) + 1;
    i_last = __text.begin() + __text.find( ">", 0 );

    text.assign( i_first, i_last );
}



657 名前: デフォルトの名無しさん 投稿日: 03/01/28 18:31
>>656
例えばこんなのはどうか。

std::string text;
std::string __text;
std::string::iterator i_first;
std::string::size_type st;

i_first = __text.begin() + __text.find("<") + 1;
st = __text.find(">") - __text.find("<") - 1;

text.assign(i_first, st);


658 名前: デフォルトの名無しさん 投稿日: 03/01/28 18:41
これでもいい。
std::stringはイテレータよりもインデックスで扱った方が
扱いやすいようだ。

std::string text;
std::string __text("aaa<abc>def");
std::string::size_type st, st2;

st = __text.find("<") + 1;
st2 = __text.find(">") - __text.find("<") - 1;

text = __text.substr(st, st2);


659 名前: デフォルトの名無しさん 投稿日: 03/01/28 18:57
文字列が"abd>efg<hijklmn"とかだと破綻しねぇか? 全部。


660 名前: デフォルトの名無しさん 投稿日: 03/01/28 18:59
>>659
エラーチェックしてないから。したらしたなりになる。


661 名前: デフォルトの名無しさん 投稿日: 03/01/28 20:21
>>656
boost::regex使えばいいのに。


662 名前: 656 投稿日: 03/01/28 20:36
正規表現で探すのは後に実装する予定でした。
とりあえず抽出だけを考えてます
それで、関数を作ってみました。

const std::string Extraction
(
const std::string text,
const std::string text_open,
const std::string text_close
)
{
std::string output = "";
std::string::size_type position_open = 0;
std::string::size_type position_close = 0;
std::string::size_type position_target = 0;

position_open = text.find( text_open, 0 );
if( position_open == std::string::npos ) return ( const std::string )"";

position_close = text.find( text_close, position_open );
if( position_close == std::string::npos ) return ( const std::string )"";

position_target = position_open + text_open.length();

output.assign( text, position_target, position_close - position_target );

return ( const std::string )output;
}



663 名前: 656 投稿日: 03/01/28 20:37
使用してみました

std::string t;
t = Extraction( "a<b<c<d", "<", ">" ); // 無
t = Extraction( "a<b<c>d", "<", ">" ); // b<c
t = Extraction( "a<b>c<d", "<", ">" ); // b
t = Extraction( "a<b>c>d", "<", ">" ); // b
t = Extraction( "a>b<c<d", "<", ">" ); // 無
t = Extraction( "a>b<c>d", "<", ">" ); // c
t = Extraction( "a>b>c<d", "<", ">" ); // 無
t = Extraction( "a>b>c>d", "<", ">" ); // 無

STL 初心者なもので、色々と不具合があるかもしれません。
みなさんどうもありがとうございました


664 名前: デフォルトの名無しさん 投稿日: 03/01/29 03:31
>>662

これではいかぬか

const std::string Extraction
(const std::string& text, const std::string& text_open, const std::string& text_close)
{
std::string::size_type position_open = text.find(text_open), position_close, position_target;

if (
position_open == std::string::npos
|| (position_close = text.find(text_close, position_open)) == std::string::npos
|| (position_target = position_open + text_open.length()) > position_close
)
return std::string();
else
return std::string(text, position_target, position_close - position_target);
}


665 名前: デフォルトの名無しさん 投稿日: 03/01/29 09:00
boost::shared_ptrのような非進入型参照カウンタを使ったスマートポインタって
スマートポインタ同士の直接代入はできるけど、
スマートポインタから生ポインタを取り出して、それを別のスマートポインタに入れると参照カウントの二重管理になって悲惨な結末になるんですよね。

んで、普段は可能な限りスマートポインタを使うことでどうにかなるんですけど、
一ヶ所だけ絶対にスマートポインタが使えないところがあって、
つまり this ポインタなんですけどね。

boost::shared_ptr< MyType > MyType::GetObject( std::string name )
{
 return boost::shared_ptr< MyType >( this->name==name ? this : new MyType( name ) );
}

みたいな必要があったとき、皆さんならどうしますか?
私はもうぜんぜん思いつかないんで進入型に切り替えるしかないかなぁとか思ってますが。


666 名前: デフォルトの名無しさん 投稿日: 03/01/29 09:19
その場合MyTypeを管理している上位クラスが全部責任を持つ構造にする。


667 名前: デフォルトの名無しさん 投稿日: 03/01/31 23:37
STLportのhashって使ってみられた方いらっしゃいます?


668 名前: デフォルトの名無しさん 投稿日: 03/01/31 23:43
>>667
hash_map ではなくて、ハッシュ値を計算する hash の方? 使った事はあるけど。


669 名前: デフォルトの名無しさん 投稿日: 03/01/31 23:44
>>668
hashのアルゴリズムは処理系依存なんですよね。
どういう仕組みで発生しているのか興味があります。


670 名前: デフォルトの名無しさん 投稿日: 03/02/01 00:33
>>669
> hashのアルゴリズムは処理系依存なんですよね。
STLport の hash の話をしてるなら、処理系非依存だが。stl/_hash_fun.h に
書いてあるから読んでみ。

ちなみにテンプレートクラスとして定義されているので、ユーザ定義クラスに対する
ハッシュ値は、自分で specialization しないと計算できない。


671 名前: デフォルトの名無しさん 投稿日: 03/02/01 00:39
>>670

inline size_t __stl_hash_string(const char* __s)
{
_STLP_FIX_LITERAL_BUG(__s)
unsigned long __h = 0;
for ( ; *__s; ++__s)
__h = 5*__h + *__s;

return size_t(__h);
}

これでしょうか。割と簡単な事してるんですね。ありがとうございました。


672 名前: デフォルトの名無しさん 投稿日: 03/02/02 18:22
LokiのVC6Port(↓)にReferredTypeやPointeeTypeを実装するのは
無理かなあ?
isEnumとisMemberFuncPointerは出来たので送ったら反映されたん
だけど誰かアイデアない?

http://fara.cs.uni-potsdam.de/~kaufmann/?page=lokiport



673 名前: デフォルトの名無しさん 投稿日: 03/02/03 03:19
ファイルの内容を表示するプログラムを作ってみたのですが、
改行を表示してくれません。どこを直せば良いでしょうか。

int main()
{
std::ifstream ifs("copy1.cpp");

std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout));
}


674 名前: デフォルトの名無しさん 投稿日: 03/02/03 03:24
>>673
std::istream_iterator<type>(i)は、i >> t を内部で実行しているため、
ホワイトスペース文字はスキップされて読み込まれない。


675 名前: デフォルトの名無しさん 投稿日: 03/02/03 03:30
>>674
ありがとうございます♪
意外でした。std::getlineか何かで読み込んでみることにします。


676 名前: デフォルトの名無しさん 投稿日: 03/02/03 03:51
>>675

std::noskipwsをストリームに食わせてやれば、ホワイトスペース
文字も読み込める。

int main()
{
std::ifstream ifs("copy1.cpp");

ifs >> std::noskipws;
std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout));
}


677 名前: デフォルトの名無しさん 投稿日: 03/02/03 04:02
> ifs >> std::noskipws;

何か、「食わせてる」 って気がしないよな。


678 名前: デフォルトの名無しさん 投稿日: 03/02/03 04:21
ちなみにそういう場合は[io]streambuf_iteratorを使ったほうが速いぞ、と。


679 名前: デフォルトの名無しさん 投稿日: 03/02/03 10:23
某所で見かけた静的配列の長さを調べるコード。ちょっと感動した。

template< typename T, size_t N >
inline size_t length_of( T(&)[N] ) throw(){ return N; }

それを参考にした、静的配列の最後の要素を得るコード
template< typename T, size_t N >
inline T& last_element_of( T(&array)[N] ) throw()
{
 return array[N-1];
}



680 名前: デフォルトの名無しさん 投稿日: 03/02/03 10:56
なるほどこれなら単純で良いね。

int main()
{
std::ifstream ifs("copy1.cpp");

std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(), std::ostream_iterator<char>(std::cout));
}


681 名前: デフォルトの名無しさん 投稿日: 03/02/03 11:06
STLportって何がいいの?ラインセンスもアレだし。


682 名前: デフォルトの名無しさん 投稿日: 03/02/03 12:03
>>679
ちなみに某所ってどこよ?他にもお宝眠ってたりせんかの?


683 名前: デフォルトの名無しさん 投稿日: 03/02/03 12:47
>>682
たぶん ttp://www.kmonos.net/wlog/23.php あたりか?
でもこれ自体は別に新しくもない話題だよ。
ttp://www.ganaware.org/D/diary/2000-07.html



684 名前: 679 投稿日: 03/02/03 13:14
>>682
tp://www.issei.org/diary/ にて。
>>683
そーだったのか…


685 名前: 682 投稿日: 03/02/03 14:15
>>684
なるほろthx!
>>683
まぁまぁそう言わんと。知らん人間にとっては新しくなくても十分面白かったんで。


686 名前: デフォルトの名無しさん 投稿日: 03/02/03 21:32
>>684
その日記の元ネタは cuj web site の記事。URL を忘れたので元記事へのリンクを
張らなかったんだが、google に掛け合って見つけてきたよ。制限事項に関しても詳
しく書いてあるから、ざっと読んでおくと良いと思いかと。

http://www.cuj.com/articles/1999/9902/9902h/9902h.htm?topic=articles

これに関連した小ネタだと、std::for_each のような一定範囲を扱うアルゴリズムに
次のような多重定義をしておくってのもある。for_each や find_if は、コンテナ全部
に適用したいケースが多いから。

template <class T, class TFunc>
inline TFunc for_each(T& col, TFunc f)
{
  return std::for_each(col.begin(), col.end(), f);
}

template <class T, int N, class TFunc>
inline TFunc for_each(T (&ary)[N], TFunc f)
{
  return std::for_each(&ary[0], &ary[N], f);
}

template <class T, int N, class TFunc>
inline TFunc for_each(T const (&ary)[N], TFunc f)
{
  return std::for_each(&ary[0], &ary[N], f);
}


687 名前: デフォルトの名無しさん 投稿日: 03/02/03 23:42
lokiのSmartPtrを使ってるひとはいますか?
あれがもっとも汎用的でいいと思うのですが
なんでboostには含まれないのかな?


688 名前: デフォルトの名無しさん 投稿日: 03/02/03 23:54
>>687
つかってまつ。gcc 2,95のバグに悩まされました。


689 名前: デフォルトの名無しさん 投稿日: 03/02/03 23:56
>>687
いま、ちょうどboostのMLでLokiの人含めて色々議論してるようだから読んでみれば?


690 名前: デフォルトの名無しさん 投稿日: 03/02/03 23:59
>>687
boost-mlでなんか今 auto_ptr みたいな挙動をどーするか
議論してるよ。boostに取り込まれる予定なはず。いつかは知らんけど。


691 名前: 690 投稿日: 03/02/04 00:00
ぐはぁ、かぶった。逝ってきまふ・・・


692 名前: デフォルトの名無しさん 投稿日: 03/02/04 00:11
>>691
逝かんで良いから、議論の流れをザクッと要約してくれると嬉しい。


693 名前: 690 投稿日: 03/02/04 00:53
>>692
無理でふ。サラッと見ながら
「あー、なんかモメてるっぽいなぁ」
程度にしか読んでいないので・・・
「結論出たら結論だけ見ればいいや」
と思ってるんであんま(全然)流れ追ってないんですわ。

ちなみに今は配列のサポートでまた何やら議論してるみたい。
これも別にマトモに追ってないんですけど。


694 名前: デフォルトの名無しさん 投稿日: 03/02/04 02:02
>>680
単純がいいなら、こっちにしとけば?
main()
{
std::ifstream ifs("copy1.cpp");
std::cout << ifs.rdbuf();
}



695 名前: デフォルトの名無しさん 投稿日: 03/02/04 02:09
>>694
何と!簡単ですね!


696 名前: デフォルトの名無しさん 投稿日: 03/02/04 05:52
それってどれくらいメモリ食うの?


697 名前: デフォルトの名無しさん 投稿日: 03/02/04 10:30
>>686
参考になりました。Thanks!


698 名前: デフォルトの名無しさん 投稿日: 03/02/04 11:15
>>696
「それ」ってなに?


699 名前: デフォルトの名無しさん 投稿日: 03/02/04 11:17
>>698
>>694


700 名前: デフォルトの名無しさん 投稿日: 03/02/04 11:28
>>699
なんで「メモリ食う」なんて思ったんだ?
ファイルの読み取りバッファと標準出力の
書き込みバッファくらいしか思いつかないんだが。


701 名前: デフォルトの名無しさん 投稿日: 03/02/04 11:48
>>700
いや、内部的に何が起こるのかなと思って。


702 名前: デフォルトの名無しさん 投稿日: 03/02/04 12:15
>>701
「内部的」なことは当然わからんが、
1文字ずつ読んだ場合に比べて余分に
メモリを必要とする理由はなにもない。


703 名前: デフォルトの名無しさん 投稿日: 03/02/05 15:24
低レベルな質問で申し訳ないですが,
binary_function<Arg1, Arg2, RetVal>にはoperator()
定義されてないんでしょうか?
cout << plus<int>()(2,3) << endl;
は上手くいくのに,
binary_function<int, int, int> fn = plus<int>();
cout << fn(2, 3) << endl;
は上手くいきません.



704 名前: デフォルトの名無しさん 投稿日: 03/02/05 15:33
>>703
定義されてない。
operator()は仮想関数じゃないよ。


705 名前: 703 投稿日: 03/02/05 15:46
では,関数オブジェクトを引数として渡したい場合は,
引数の型は何にしたらいいんでしょうか?



706 名前: デフォルトの名無しさん 投稿日: 03/02/05 15:54
>>705
ふつうはテンプレートの型引数だな。
template<typename BinaryFunction>
void f(BinaryFunction fn);


707 名前: 703 投稿日: 03/02/05 15:57
<algorithm>以下の関数でもそうしてましたが,
テンプレートで取り込もうとすると,
色々と面倒な事起こりませんか?
出来れば,引数として取り込みたいのです.



708 名前: デフォルトの名無しさん 投稿日: 03/02/05 15:59
>>707
別に面倒なことなんかないが?


709 名前: 703 投稿日: 03/02/05 16:02
すいません.↑意味不明でしたね.
様はtemplateは使わずに,
void f(binary_function<int, int, int> fn);
みたいな感じで使いたいのです.
binary_functionはlessやらplusやらの基底クラスらしいですが,
共通に使われるであろうoperator()を仮想関数として定義
してないんじゃ使えないですね.
引数としてこのクラスの関数オブジェクトを読み込む場合,
この代わりに何を基底クラスとして使うべきなのでしょうか?


710 名前: 703 投稿日: 03/02/05 16:03
>>709
templateを使って定義すると,
ソースコードをいちいちincludeしないといけなくなりませんか?



711 名前: デフォルトの名無しさん 投稿日: 03/02/05 16:04
>>709
そんな方法はない。お前はbinary_functionの存在理由を大幅に誤解している。


712 名前: デフォルトの名無しさん 投稿日: 03/02/05 16:05
>>709
そうなると、基底クラスじゃぁないが、boost::functionなんだろうなぁ。


713 名前: デフォルトの名無しさん 投稿日: 03/02/05 16:06
>>709
binary_functionはtypedef導入用のテンプレートであって、
多態で使うことを目的としたものじゃない。

> void f(binary_function<int, int, int> fn);
何故templateにしないでこうしたいのかがよく
わからんが、とりあえず boost::function 使え。


714 名前: 703 投稿日: 03/02/05 16:12
>>712
STLじゃ無理なんですね.


715 名前: デフォルトの名無しさん 投稿日: 03/02/05 20:21
>>709
binary_function は引数、戻り値の型を class 内の typedef として定義するための
クラス。それ自身はなんの機能も持たない。

Generic Programming あたりを読んでお勉強するのが良いと思われ。


716 名前: デフォルトの名無しさん 投稿日: 03/02/06 00:25
BCCで、
テンプレート引数の整数はunigned int ではだめで、特別化がおきず、intにしなくてはいけません。
これってC++の仕様ででしょうか?整数引数単独のテンプレはOK。

#include<iostream>
template<class T,unsigned int Sz>
struct vector{
public:
vector(){std::cout << "Standard" <<std::endl;}
};
template<class T>
struct vector<T,3>{
public:
vector(){std::cout << "Special" <<std::endl;}
};

int main(){
vector<double,1> v1;//Standard
vector<double,3> v3;//Specialになってほしいが・・・
return 0;
}


717 名前: デフォルトの名無しさん 投稿日: 03/02/06 00:38
>>716
BCC5.6.2だとちゃんとSpecialになるよ。


718 名前: デフォルトの名無しさん 投稿日: 03/02/06 12:00
>>717
お、そうですか・・・。BCC5.5のバグなんですね。ありがとうございます。


719 名前: デフォルトの名無しさん 投稿日: 03/02/06 13:33

VC++7.0 で、以下の式が正しく通るんだけど…

 // ↓LokiPort for VC++7.0
 Loki::SmartPtrDef<MyClass>::type sp( new MyClass );
 sp[ 2 ];

犯人は特定できたけど、この仕様のおかげで、
自作の添え字演算子を持つポリシーが使えないじゃないかっ!





720 名前: デフォルトの名無しさん 投稿日: 03/02/06 16:50
>>719

音無しくboost::shared_arrayにするよろし


721 名前: デフォルトの名無しさん 投稿日: 03/02/06 18:28
>>719
犯人は?


722 名前: デフォルトの名無しさん 投稿日: 03/02/06 20:49
ヤス


723 名前: デフォルトの名無しさん 投稿日: 03/02/07 02:45
>>722
いつのネタだよ。
ポートピア連即殺人事件の中の人も大変だな。



724 名前: デフォルトの名無しさん 投稿日: 03/02/07 09:25
>>719
operator Tester*()
こいつのおかげで、operator[] が曖昧だといわれてしまう。

>>723
中の人な(ry


725 名前: 722 投稿日: 03/02/07 09:44
>>723
通じるなら立派なネタじゃないか


726 名前: デフォルトの名無しさん 投稿日: 03/02/07 12:58
ザクの犯人はシャア


727 名前: デフォルトの名無しさん 投稿日: 03/02/07 17:54
templateの型推測のアルゴリズムが今ひとつわかりにくかったので
良書を探していたら、C++Primerが目に止まった。

この本はC++初心者用だからと今まで目もくれなかったが、今日
何気に立ち止まって読んでみると、templateについてじつに詳しく
書いてある。これだけでも買う価値があると思い、速攻レジへ。

本の厚さに圧倒されつつも、読んでいます。アルゴリズムについて
も相当詳しい解説があります。でもアルゴリズムは一通りやった
んだけどな。


728 名前: 724 投稿日: 03/02/07 18:24
>>724>>719 へのレスは、>>720 へのレス


729 名前: デフォルトの名無しさん 投稿日: 03/02/08 00:14
treeコンテナ でおすすめなものないでしょうか?


730 名前: デフォルトの名無しさん 投稿日: 03/02/08 00:21
>>729
二分木コンテナ?何に使うの?


731 名前: デフォルトの名無しさん 投稿日: 03/02/08 02:36
>>729
set とか map とか、内部実装的には tree になってるよ。
ちなみに、STL で使われてる平衡木アルゴリズムは二色木(red black tree)。



732 名前: デフォルトの名無しさん 投稿日: 03/02/08 02:36
>>730
バランス木または多分木のコンテナが欲しいです。
ゲームの探索に使おうと思ってます。



733 名前: デフォルトの名無しさん 投稿日: 03/02/08 02:48
>>732
要するに、そのゲームに特化した最適な構造の木を使いたいってこと?
そんな特定用途向けのライブラリ、早々転がってないぞ。

とりあえず、STL ので我慢して作って、
パフォーマンス的にどうしても必要になったら改めて自作しろ。



734 名前: デフォルトの名無しさん 投稿日: 03/02/08 11:16
2つの型が同じかどうか判定することってできるでしょうか

template<typename A, typename B>
bool IsSameType();

いろいろ考えましたが思いつきませんでした・・・


735 名前: デフォルトの名無しさん 投稿日: 03/02/08 13:18
>>731
std::map をどうやって「木として」使うんだ?

>>729
平衡木なら http://www.essemage.com/aapl/ とかが有名どころではなかろうか。
多分木はあんまり見たこと無いなぁ。

>>734
template<typename A, typename B> struct ist { enum{ val = 0 }; };
template<typename A> struct ist<A,A> { enum{ val = 1 }; };

template<typename A, typename B>
bool IsSameType() { return ist<A,B>::val; }


736 名前: デフォルトの名無しさん 投稿日: 03/02/08 14:04
>>729
http://www.damtp.cam.ac.uk/user/kp229/tree/

ってなモノがある。昔boost-mlに流されたけどどーなったんだっけか?
まぁただGPLという最大の罠があるわけだが。


737 名前: デフォルトの名無しさん 投稿日: 03/02/08 22:44
class A1;
class A2;
...

class B {
private:
A1 a1;
A2 a2;
...
public:
};

の時にa1、a2に[]を使ってアクセスする方法はないでしょうか?



738 名前: デフォルトの名無しさん 投稿日: 03/02/08 23:15
#define private public


739 名前: 738 投稿日: 03/02/08 23:17
あ、違った。失礼。
まぁ、operator[]でも定義しなさいってこった。


740 名前: 737 投稿日: 03/02/08 23:24
A1,A2,・・・がA_Baseから派生していて、a1,a2が配列要素になっていたら
[ ]を定義できるのですが、この場合どうやったらいいか分かりません。
また上記の場合派生して加えた関数にアクセス出来ません。templateを使って旨く出来ないでしょうか?



741 名前: 738 投稿日: 03/02/09 00:25
ん?
B::operator[]
をテキトーに定義してやるんじゃマズいの?
なんか良く意味が分かんないんだけど。


742 名前: デフォルトの名無しさん 投稿日: 03/02/09 00:44
>>737
B b; があって、
b[0]がa1、b[1]がa2を返すとか、そういう事かい?


743 名前: 737 投稿日: 03/02/09 00:44
switchでべた書きでは無くて何か巧くできないものかと思いまして。



744 名前: 737 投稿日: 03/02/09 00:46
>>742 そんな感じです。
B b;
で、b[0].func(hoge) とか出来ない物かと。



745 名前: デフォルトの名無しさん 投稿日: 03/02/09 00:57
>>744
A1とA2が継承関係にでもないと、一つの[]でA1とA2両方返すのは
難しくないかい?


746 名前: デフォルトの名無しさん 投稿日: 03/02/09 01:09
なんかすっきりせんな。

struct A1 {
virtual void func() { std::cout << "A1" << std::endl; }
};

struct A2 : public A1 {
void func() { std::cout << "A2" << std::endl; }
};

struct B {
A1 a1;
A2 a2;
A1* operator[](int i) {
if (i == 0) return &a1;
else return &a2;
}
};

int main()
{
B b;
b[0]->func();
b[1]->func();
}


747 名前: 738 投稿日: 03/02/09 01:10
あぁ、そっかそっか。
>>744
で、[]の引数はやっぱコンパイルタイムには決まらんの?
決まるんなら boost::tuple みたいな事すれば
b.get<0>().func(hoge)
なら出来る・・・かな?



748 名前: デフォルトの名無しさん 投稿日: 03/02/09 01:11
friendとtemplateの特殊化を使って実装しようかと試みたが、[]は
メンバ関数でないとだめみたいだしなあ。friend使えたら何とか
なったかもしれんのだが。


749 名前: デフォルトの名無しさん 投稿日: 03/02/09 01:14
だめだこれでも継承関係しか受け付けない。

struct A1 {
virtual void func() { std::cout << "A1" << std::endl; }
};

struct A2 : public A1 {
void func() { std::cout << "A2" << std::endl; }
};

struct B {
A1 a1;
A2 a2;
A1& operator[](int i) {
if (i == 0) return a1;
else return a2;
}
};

int main()
{
B b;
b[0].func();
b[1].func();
}


750 名前: デフォルトの名無しさん 投稿日: 03/02/09 01:17
可能だとしても、そんなオーバーロードは認めたくないね。


751 名前: 737 投稿日: 03/02/09 01:48
皆さんありがとうございます。難しいのですね。
>>747 さんの方法も含めて考えてみます。
出来るだけpublicにはしないように頑張っているのですが、初心者には中々難しいです。



752 名前: デフォルトの名無しさん 投稿日: 03/02/09 01:53
struct A1 {
void func() { std::cout << "A1" << std::endl; }
};

struct A2 {
void func() { std::cout << "A2" << std::endl; }
};

struct B {
A1 a1;
A2 a2;
void* operator[](int i) {
if (i == 0) return &a1;
else return &a2;
}
};

int main()
{
B b;
reinterpret_cast<A1*>(b[0])->func();
reinterpret_cast<A2*>(b[1])->func();
}


753 名前: デフォルトの名無しさん 投稿日: 03/02/09 01:58
派生クラスの関数呼び出すんなら、配列(的)にする意味あるの?


754 名前: 737 投稿日: 03/02/09 02:10
>>753
B b[100];
としたいので、b[1][1].func(hoge)って呼べた方が楽だなぁと思ったのです。

>>752 ありがとうございます。参考にさせて頂きます。



755 名前: デフォルトの名無しさん 投稿日: 03/02/09 02:13
>>754
> としたいので、b[1][1].func(hoge)って呼べた方が楽だなぁと思ったのです。
激しく読みにくいコードのような気がするが…

面倒でも、素直に「役割」を反映したメソッドを書いて deletate した方が
良いと思うぞ。


756 名前: 737 投稿日: 03/02/09 02:25
>>755 そうですか・・・。頑張ってみます。



757 名前: デフォルトの名無しさん 投稿日: 03/02/09 23:35
>>734
> 2つの型が同じかどうか判定することってできるでしょうか
boostの、<boost/type_traits.hpp>をインクルードして、
boost::is_same<T, U>::value
でいけるようだが、中身を見ても何をしているのか解らなかった・・・。


758 名前: 729 投稿日: 03/02/10 09:30
>>730-736
結局、色々やるには自分で作った方がいいという結論になったのですが、
上記の物は参考にはなりました。
ありがとうございました。

//構造的にはこんな感じ
template <typename _Elem> class tree
{
tree *parent;
list<tree*> m_child;
_Elem m_element;
};




759 名前: デフォルトの名無しさん 投稿日: 03/02/10 10:48
spirit & phoenix
ホントにキタ━━━━━━(゚∀゚)━━━━━━ !!!!!


760 名前: デフォルトの名無しさん 投稿日: 03/02/10 18:11

スレ違いかもしれんけど、いい知恵を貸してください。

COMなんかで使用する BSTR は ATLインターナル等を読む限り、
「長さをプレフィックスとするOLECHAR型の文字列」だそうです。
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
で、これを std::basic_string で表現したいと思い、
char_traits をいじり始めたのですが、
「長さをプレフィックスとする」の部分で躓きました。

このような長さを先頭にもつ文字列を basic_string で表現する
うまい手段があったら教えてください。



761 名前: デフォルトの名無しさん 投稿日: 03/02/10 18:21
>>760
basic_stringで表現するより、
別のクラスにしてbasic_stringと相互?変換できるようにするほうが楽じゃないの?


762 名前: デフォルトの名無しさん 投稿日: 03/02/10 18:25
760はマルチ


763 名前: デフォルトの名無しさん 投稿日: 03/02/10 21:28
ここでシェルスクリプトのこと聞いてもいいでつか?
それとももっと適した板があるなら教えてくだたい


764 名前: デフォルトの名無しさん 投稿日: 03/02/10 21:32
>>763
シェルスクリプトならUNIX板とかLinux板とかでないかね


765 名前: デフォルトの名無しさん 投稿日: 03/02/10 22:45
>>760
どっちみち、一般のヒープ管理関数じゃなくてSysAllocStringで確保しなきゃいけないわけだし、
プレフィックス部分はポイントされている番地より「前」に存在するわけだし、
いじるならchar_traitsじゃなくてallocatorのほうではないか。
char_traitsはそのままstd::char_traits<wchar_t>でいい気がする。


766 名前: デフォルトの名無しさん 投稿日: 03/02/11 21:38
void wfstream::open
(const char* __s, ios_base::openmode __mod = ios_base::in)

ファイル名が、なぜ wchar_t でなく char なのでしょうか?



767 名前: デフォルトの名無しさん 投稿日: 03/02/12 20:36
VC7で以下が通らないのはVC7のバグ?それとも俺の思い違い?

#include <iostream>
#include <memory>

class A
{
public:
void Print(void){ std::cout << "OK" << std::endl; }
};

int main()
{
std::auto_ptr< A > ptr( new A() );

void (A::*method)(void) = A::Print;
(ptr->*method)(); // ここや

return 0;
}




768 名前: デフォルトの名無しさん 投稿日: 03/02/12 21:01
ptr->* って、std::auto_ptr<A>型についてのメンバ関数へのポインタを
探すことにならんか?


769 名前: デフォルトの名無しさん 投稿日: 03/02/12 21:12
>>767
ptrはA型へのポインタだから、当然Aの中にmethodというメンバ
がないとエラーになる。

struct A {
int i;
}

std::auto_ptr<A> ptr(new A);
int j;
ptr->j;

としているのと極端に言えば同じ。


770 名前: デフォルトの名無しさん 投稿日: 03/02/12 21:17
スマソ>>769は間違いです。見逃してくれ。


771 名前: デフォルトの名無しさん 投稿日: 03/02/12 21:24
A* a;
(a->*method)();

としたら通るね。ということは、std::auto_ptrの->演算子の多重定義
の問題なのだろう。
->の先がメンバー関数へのポインタだった場合、正常に解釈して
くれないのでは。


772 名前: 766 投稿日: 03/02/12 21:32
どうか見捨てないで下さい


773 名前: デフォルトの名無しさん 投稿日: 03/02/12 21:34
((*ptr).*method)()
にしれ


774 名前: デフォルトの名無しさん 投稿日: 03/02/12 21:54
>>767
auto_ptr<> には operator->* というメンバ関数はないので
どのコンパイラでも無理だ。


775 名前: デフォルトの名無しさん 投稿日: 03/02/12 22:20
あっそうか!->という演算子ではなくて->*という演算子なのだね。
((*ptr).*method)() が通るという事は、.*は定義されているのかな。


776 名前: デフォルトの名無しさん 投稿日: 03/02/12 22:23
>>775
(*ptr)の時点で A* になってる


777 名前: デフォルトの名無しさん 投稿日: 03/02/12 22:24
あ、ちがうか、A&か。


778 名前: デフォルトの名無しさん 投稿日: 03/02/12 22:33
>>776>>777
なるほどよく理解できました。
そしたら、((*ptr.get()).*method)();が通る理由も理解できます。


779 名前: 767 投稿日: 03/02/12 22:44
>>773

ってゆーかその手に気付かなかった自分が恥ずかしいよ。
->が定義されてるなら->*も自動だと思ったんだけどそうじゃなかったんだな。
ためしに->*を定義してみたらなかなか面白いことになったけどいまいち使いどころがわかんね。


780 名前: デフォルトの名無しさん 投稿日: 03/02/12 22:47
->* って定義できたっけ?


781 名前: デフォルトの名無しさん 投稿日: 03/02/12 23:00
>>780
できるよ。


782 名前: デフォルトの名無しさん 投稿日: 03/02/12 23:06
でも逆に .* は定義できないんだよね。
->*が定義できるのだから、今度の新しい標準C++はstd::auto_ptrにも
定義して欲しいものだ。


783 名前: デフォルトの名無しさん 投稿日: 03/02/12 23:21
operator->* をユーザー定義して普通の ->* と同じ動作をするものを
作ろうと思ったら、boost::bind 完全再生産、くらいのレベルで大変なんだけど、
なんであんな規格なんだろう。


784 名前: デフォルトの名無しさん 投稿日: 03/02/13 13:29
オーバーロードできない演算子って、
. .* :: ?: sizeof # ##
で全部?


785 名前: デフォルトの名無しさん 投稿日: 03/02/13 13:42
スマートポインタが->*をサポートするには何を返せばいいんだ?
->が返すのは生ポインタだよね。


786 名前: デフォルトの名無しさん 投稿日: 03/02/13 16:07
>>784
typeid


787 名前: デフォルトの名無しさん 投稿日: 03/02/13 17:56
>>785
こんな感じかと

#include <iostream>
#include <functional>

class A
{
public:
int b;
void hoge( int v ){ std::cout << b << v << std::endl; }

public:
template< typename type >
type& operator ->*( type A::*p ){ return this->*p; }
template< typename type >
std::binder1st< std::mem_fun1_t< type, A, int > >
operator ->*( type (A::*p)( int ) ){ return std::bind1st( std::mem_fun1( p ), this ); }
};

int main()
{
A a;
int A::* pb = &A::b;
a->*pb = 10;
void (A::*phoge)( int ) = A::hoge;
(a->*phoge)( 20 );
}



788 名前: デフォルトの名無しさん 投稿日: 03/02/14 01:24
>>784
throw 演算子もできないような気もするが……できるならサンプルプリーズ


789 名前: 785 投稿日: 03/02/14 04:00
>>787 にゃるほど。少し分かりました。thx.


790 名前: デフォルトの名無しさん 投稿日: 03/02/14 08:12
>>787
凄すぎ。このコードを理解するように努めてみます。


791 名前: 784 投稿日: 03/02/14 14:35
>>786
忘れてました。ども。

そういえば、std::XXX_cast<> 達はキャスト「演算子」なのですかね。
だとしたらオーバーロードできない、でいいと思うけど。

>>788
手元のプログラミング言語C++ 第2版では、throw は演算子じゃなくて式(の一部)のようです。

第3版がほすぃ・・・。


792 名前: デフォルトの名無しさん 投稿日: 03/02/15 07:19
listのeraseで自分のコンテナ以外の反復子を削除できるようなのですが、
この使用は抑止した方がいいのでしょうか?

#include<list>
#include<iostream>
#include<string>
#include<vector>
using namespace std;

int main()
{
list< vector<string> > a,a2;

vector<string > s,s2;
s.push_back("111");
s2.push_back("222");

a.push_back(s);
a2.push_back(s2);

a.erase(a2.begin()); //aのeraseでa2の反復子を削除する。
//list<T>::eraseのソースをみると
//_Mysize--;となっているが、
//_Mysize=size();としないと矛盾しないか?(debbugerのsizeも0,1になってる)

cout << "a size:" << (*(a.begin())).size() << std::endl;
cout << "a2 size:" << (*(a2.begin())).size() << std::endl;//a2の要素は削除されてる
//これはbegin()とend()から計算してるから大丈夫。

cout << "*a.begin():" << *(*(a.begin())).begin() << std::endl;//111
}



793 名前: デフォルトの名無しさん 投稿日: 03/02/15 12:27
>>792
実装的にその方が楽なんよ。
STLは計算効率至上主義だからそういう風になってるんだと思われ。

ほんとはそういうまねは出来ない方がいい。




794 名前: 792 投稿日: 03/02/15 15:51
>>793
ちと勘違いしてたんで、修正した。
サイズ等の状態数を管理するのって危険が伴うのにそれを完全に排除してない
方が悪い気がするんだけど。

//上と同じ

int main()
{
list< vector<string> > a,a2;

vector<string > s,s2;
s.push_back("111");
s2.push_back("222");

a.push_back(s);
a2.push_back(s2);

a.erase(a2.begin()); //aのeraseでa2の反復子を削除する。
cout << "aのeraseでa2の先頭の反復子を削除する" << std::endl;

cout << "a.size() :" << a.size() << std::endl; // VC 0 ,GCC 1
cout << "a2.size():" << a2.size() << std::endl; // VC 1 ,GCC 0

cout << "(*a::begin()).size()) :" << (*(a.begin())).size() << std::endl; // VC 1 ,GCC 0
cout << "(*a2::begin()).size()):" << (*(a2.begin())).size() << std::endl; // VC 1 ,GCC 0

cout << "*(*(a.begin())).begin() :" << *(*(a.begin())).begin() << std::endl;//111
//cout << "*(*(a2.begin())).begin():" << *(*(a2.begin())).begin() << std::endl;//
}



795 名前: 794 投稿日: 03/02/15 16:06
>>794
よくみたらミスってました...。
cout << "(*a::begin()).size()) :" << (*(a.begin())).size() << std::endl; // VC 1 ,GCC 1
cout << "(*a2::begin()).size()):" << (*(a2.begin())).size() << std::endl; // VC 0 ,GCC 0
であってると思います。



796 名前: デフォルトの名無しさん 投稿日: 03/02/16 00:56
>>794
Sequence::erase の Precondition を破っているので、
未定義動作でしょうがないと思われ。



797 名前: デフォルトの名無しさん 投稿日: 03/02/16 02:30
STLport 使ってて(iostreamは使用せず)
ICU使いたいんですけど
STLportのスタティックライブラリにする必要あります?
経験者の方教えてください。


798 名前: 794 投稿日: 03/02/16 08:16
>>796
同じ型のコンテナ内の反復子を矛盾なく削除できる関数として
機能したほうがいいと思うんだけど。
その代わり、多少パフォーマンスは下がってしまうか。

コンテナが反復子の状態数を保存してるときは
反復子を操作(削除)するときに
管理しているコンテナに通知して処理するほうが望ましい結果が得られる。


799 名前: デフォルトの名無しさん 投稿日: 03/02/16 09:03
Boostsを使いたいのですがどこか日本語で詳しく解説してあるサイトか本はありませんか?
あったら教えてください。


800 名前: デフォルトの名無しさん 投稿日: 03/02/16 09:09
>>799
http://user.ecc.u-tokyo.ac.jp/~g940455/wp/boost/index.html
http://www.emaki.minidns.net/Programming/tools/Boost/
http://www.kmonos.net/alang/boost/


801 名前: デフォルトの名無しさん 投稿日: 03/02/16 09:12
Let's boost
ttp://www.kmonos.net/alang/boost/


802 名前: デフォルトの名無しさん 投稿日: 03/02/16 09:26
>>798
iteratorは基本的に自分が属するContainerがどれであるかを知らないし、
Containerは基本的に自分の上のiteratorがどこかに存在しているかどうかを
知らないし、
algorithmは自分が操作する対象がどんなsequenceであるかを知らない…

という形にすることで可能な限り一般性を高める、というのが
STLの方向性だと思うので、↓の是非は別にして、
> コンテナが反復子の状態数を保存してるときは
> 反復子を操作(削除)するときに
> 管理しているコンテナに通知して処理するほうが望ましい結果が得られる。
これはSTLに求める性質としてはお門違いではないかと。


803 名前: 799 投稿日: 03/02/16 09:28
>>800 , 801
ありがとうございます。
自分でさがせ、殺すぞ、とか言われるかと思いましたがやさしいですね。


804 名前: 794 投稿日: 03/02/16 12:40
>>802
一般的な反復子にはもちろん同意だが、
コンテナ内のtypedef(または定義)されたiteratorを
削除するときは違う。
a.insert(a2.begin()) -> は問題ない
a.erase(a2.begin()) -> a2側に通知が必要

STLの性質を求めてるんじゃなくて、
結果が正しくなることを求めてる。



805 名前: デフォルトの名無しさん 投稿日: 03/02/16 13:03
使い方が間違ってるのに結果が正しくなるのは無理だと思われ


806 名前: デフォルトの名無しさん 投稿日: 03/02/16 13:22
>>804
自分で勝手に自分がどのコンテナオブジェクトに属しているかを知っている
イテレ−タを使ってアクセスされるリストクラスでも作って使っとけアホ。


807 名前: デフォルトの名無しさん 投稿日: 03/02/16 14:05
とりあえず話を>>792に一旦戻すと、
> listのeraseで自分のコンテナ以外の反復子を削除できるようなのですが、
自分のコンテナ以外の反復子を指す要素は削除「できない」。実装によっては
たまたま削除されてしまうかもしれないが、その辺りの動作は未定義。

それをふまえて。

> a.insert(a2.begin()) -> は問題ない
a.insert(a2.begin, value) か? a.erase(a2.begin()) と同じ程度には問題あるだろう。

> 結果が正しくなることを求めてる。
sqrt( "弐" ) とやったら "1.41421356" と返すのが正しい結果だ、
と主張してそれを求めてるのに等しいことは自覚してるか?

無論、sqrt( "弐" ) と同じでコンパイルエラーになるとか、最悪でも
実行時エラーになったら嬉しいのは確かだし、(だからSTLPortの
Debug版とかはかなり重宝されている。) staticメンバ関数を使って
list<T>::erase(a2.begin()) と書けるiterator/container はそれなりに便利だろう。
が、それはSTLの範疇じゃない。


808 名前: 807 投稿日: 03/02/16 14:06
×反復子を指す要素
○反復子の指す要素


809 名前: デフォルトの名無しさん 投稿日: 03/02/16 14:07
>>806
ひとこと余計なんだよ。
カスが。


810 名前: デフォルトの名無しさん 投稿日: 03/02/16 19:14
STL含んでいるObjectを、Exe <-> Dll 間で使用していると
保護違反が発生するのですが、STLはExeをまたがって使用できないのですか?

環境は .Net STLはMS製です。


811 名前: デフォルトの名無しさん 投稿日: 03/02/16 19:31
>>810
MSの作るのDLL/EXEは、MSVCRT.DLLを使わない限り、ヒープを個別に
持つことになる。片方でnew/mallocしたものを他方でdelete/freeすると
当然おかしなことになる。
MSVCRT.DLLを使うか、またがってnew/deleteをしないよう
気をつけるしかない。


812 名前: デフォルトの名無しさん 投稿日: 03/02/16 19:54
重複項を省くためにsetを使っているですが、
list<N>::iteratorの比較をしたい場合には、どのようにしたら良いのでしょう?

list<N>::iterator il; // Nは適当なクラス
set<list<N>::iterator> lset;
lset.insert(il); // 必要なilを適宜追加する。ここでの重複を省きたい。

(とりあえずコンパイル通すために)以下のようにiteratorの比較をしています
bool operator < (const std::list<N>::iterator lhs, const std::list<N>::iterator rhs)
{ return &(*lhs) < &(*rhs); }

g++(2.96〜3.2)では通るのですが、Intel Compiler(icc)では、
# error: no operator "<" matches these operands
# operand types are: const std::list<N, std::allocator<N>>::iterator
# < const std::list<N, std::allocator<N>>::iterator
とはじかれてしまいます。

どうすれば解決するかご指摘いただけないでしょうか?


813 名前: デフォルトの名無しさん 投稿日: 03/02/16 20:08
template< typename Iterator >
struct compare_dereferenced_address : std::binary_function< bool , Iterator , Iterator >
{
  bool operator () const ( const Iterator& lhs , const Iterator& rhs )
  { return &(*lhs) < &(*rhs); }
};

set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset;

Interl Compiler 持ってないから、実験はできないけど、
とりあえず行儀よくしてやったら治らないかね?


814 名前: sage 投稿日: 03/02/16 21:01
>>811
レスありがとうごさいます。
>またがってnew/deleteをしな気をつけるしかない。
この修正してきます


815 名前: 812 投稿日: 03/02/16 21:13
>813
治りました。ありがとうございます。

binary_functionにあまり馴染んでないせいか(必要にかられて本を調べる程度)
set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset;
こんな風に宣言できることすら思いつきませんでした。


816 名前: デフォルトの名無しさん 投稿日: 03/02/16 21:31
boostとstdの function の Resultの位置は逆になってたような...。



817 名前: 813 投稿日: 03/02/16 21:46
コンパイルが通るだけに、恐ろしい罠だのぅ。


818 名前: 812 投稿日: 03/02/17 04:49
解決したつもりになっていたのですが、、、

set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset;
とすると確かに通るのですが、挙動不審です。
どうも元の set<list<N>::iterator> との型の互換で失敗しているようです。
この辺のデバッグが非常に面倒なプログラムなので、
できれば素の、set<list<N>::iterator>のまま通したいところです。切実に、、

せっかく
bool operator < (const std::list<N, std::allocator<N> >::iterator lhs,
const std::list<N, std::allocator<N> >::iterator rhs)
{ return &(*lhs) < &(*rhs); }
と、operator用意しているのに、何で使ってくれへんの? と悲鳴をあげつつ
以下がエラーメッセージ全文となります。うざったくてすんません。
どうか、もちょっとだけアドバイスを下さいませ。

/opt/intel/compiler70/ia32/include/functional(134): error: no operator "<" matches these operands
operand types are: const std::list<N, std::allocator<N>>::iterator
< const std::list<N, std::allocator<N>>::iterator
return (_Left < _Right);
^
detected during:
instantiation of "bool std::less<_Ty>::operator()
(const _Ty &, const_Ty &) const [with _Ty=std::list<N, std::allocator<N>>::iterator]"
at line 471 of "/opt/intel/compiler70/ia32/include/xtree"

instantiation of "std::_Tree<_Traits>::_Pairib std::_Tree<_Traits>::insert(const std::_Tree<_Traits>::value_type &)
[with _Traits=std::_Tset_traits<std::list<N, std::allocator<N>>::iterator,
std::less<std::list<N, std::allocator<N>>::iterator>,
std::allocator<std::list<N, std::allocator<N>>::iterator>, false>]"


819 名前: デフォルトの名無しさん 投稿日: 03/02/17 06:53
> set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> > lset;
> とすると確かに通るのですが、挙動不審です。
> どうも元の set<list<N>::iterator> との型の互換で失敗しているようです。

失敗じゃネェよ。そいつらは違う型だ。
set<list<N>::iterator>を使ってたところで全部同じ型を使うように汁。


820 名前: デフォルトの名無しさん 投稿日: 03/02/17 08:01
>>818
多分
 template<typename T> void function( tmpl<T> t ) { ... }
という定義があれば tmpl<T> t; function(t); で見つけられるけど、
 template<typename T> void function( tmpl<T>::type t ) { ... }
では tmpl<T>::type t; function(t); では見つからないはず。

# スマートポインタを ptr<T>::shared とか ptr<T>::auto とか ptr<T>::locked
# とか書きたいけど書けねぇなぁ、という議論で見かけた気がする。

ので素直に、
1: set<list<N>::iterator> を(名前は適切なものをつければいいが) set_of_N_iter に置換
2: typedef set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> >
    set_of_N_iter;
しとけ。

あるいは、iteratorの比較関数をtemplateにしないで
bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
と一個一個書いていけばいいような気もするが。


821 名前: 812 投稿日: 03/02/17 13:28
>819
>set<list<N>::iterator>を使ってたところで全部同じ型を使うように汁。
ごもっともです。
それでうまくいかなかったのは、やはり元のコードがbuggyだったせいかと。

>820
>bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
>と一個一個書いていけばいいような気もするが。
これはどうも無理でした。

>では tmpl<T>::type t; function(t); では見つからないはず。
つまり、見つけられた(コンパイラ)の方がたまたまだったというわけでしょうか……

>ので素直に、 (中略) しとけ。
はい、そうしますわ。こつこつバグ治します。


822 名前: デフォルトの名無しさん 投稿日: 03/02/17 15:34
どうでもいいけど、
ttp://groups.yahoo.com/group/boost/files/
とか見ていると、smart_ptr とか singleton とか
いい感じに Loki を取り込んでいってますな。
あと、次期 boost::lexical_cast 萌え

ところで、ここのコードって勝手に使っていいのかな?


823 名前: デフォルトの名無しさん 投稿日: 03/02/17 16:36
>>821
素朴な疑問なんだけどさあ、iteratorってお互いの大小関係って
比較できたっけ?
==か!=でしか比較できなかったような気がするんだが。


824 名前: デフォルトの名無しさん 投稿日: 03/02/17 16:40
それから、std::setの比較基準なんだけど、
1.std::set<Elem, Op>
2.std::set c(Op)
のどちらかでしか比較基準は指定できないよ。これを使わず
operator< を定義しても使ってはくれない。


825 名前: デフォルトの名無しさん 投稿日: 03/02/17 20:45
>>823-824
> 素朴な疑問なんだけどさあ、iteratorってお互いの大小関係って
> 比較できたっけ?
だから812氏は苦労して { return &(*lhs) < &(*rhs); } なんて奇怪な
比較関数を作ってるんじゃねーの?

> のどちらかでしか比較基準は指定できないよ。これを使わず
> operator< を定義しても使ってはくれない。
set<T> とやったら比較ポリシーは std::less<T> になるから、
operator < が呼ばれる。つーか、キミ、勉強し直せ。


826 名前: 820 投稿日: 03/02/17 20:50
>>821
追実験。。
> >bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
> >と一個一個書いていけばいいような気もするが。
Comeau のオンラインコンパイラで試してみたら、
 namespace std {
  bool operator<( const list<int>::iterator& i, const list<int>::iterator& j ) { ... }
 }
とstdの中に突っ込んで置いたら一応コンパイルは通ったぞい。
猛烈に行儀が悪いので、止めた方が無難だが。


827 名前: デフォルトの名無しさん 投稿日: 03/02/17 21:20
それがランダムアクセスイテレータなら大小関係の比較できる。


828 名前: 812 投稿日: 03/02/17 22:02
>826
通りました! まさにピンポイントなアドバイス!
>猛烈に行儀が悪いので、止めた方が無難だが。
よそのコンパイラでお行儀悪くするためにはコツが必要なのですね。
ありがとうございます。

>827
なるほど。const list<N>::iteratorではなく、const vector<N>::iteratorの場合、
operator < を作る必要がなかったので不思議に思っていました。
勉強になりました。


829 名前: デフォルトの名無しさん 投稿日: 03/02/19 01:45
boostやSTLportのtype_traitsをユーザー定義型で特殊化するサンプルってありますか?


830 名前: デフォルトの名無しさん 投稿日: 03/02/21 05:05
次期vsはC++標準準拠度があがるみたいだけど
もうstlport使わなくてよくなるかな


831 名前: デフォルトの名無しさん 投稿日: 03/02/21 05:06
もしかしたらVCもSTLport標準装備だったりして。


832 名前: デフォルトの名無しさん 投稿日: 03/02/21 05:10
STLの実装がいくつもあってもあんまりいいことないよね


833 名前: デフォルトの名無しさん 投稿日: 03/02/21 05:11
そろそろSTL開発会社も自然淘汰の時期だ。


834 名前: デフォルトの名無しさん 投稿日: 03/02/21 06:20
managed C++ が多重継承できませんから。
stl なんか使いませんとも。



835 名前: デフォルトの名無しさん 投稿日: 03/02/21 14:25
2つのvectorがあって、1方にだけ含まれる要素を
抜き出すにはどうすればよいですか?

片方に含まれる、両方に含まれる、どちらにも含まれる、で
処理を分けるようなこともしたいです。


836 名前: デフォルトの名無しさん 投稿日: 03/02/21 14:35
>>835
ソート済みなら
std::set_union()
std::set_intersection()
std::set_defference()
が使えるかと。


837 名前: デフォルトの名無しさん 投稿日: 03/02/21 14:36
>>835
片方にのみ含まれる - std::set_difference()
どちらにも含まれる - std::set_intersection()
両方の集合の和 - std::set_union()

但しこれらのアルゴリズムは必ず std::vectorを sort() してから
呼び出さなければならない。


838 名前: デフォルトの名無しさん 投稿日: 03/02/21 14:37
ケコーン(w


839 名前: 836 投稿日: 03/02/21 14:42
親切度低いぶんだけ早かったな俺(w


840 名前: 仕様書無しさん 投稿日: 03/02/21 15:45
簡素な即レスと、丁寧な遅レスはどっちがより親切だろう?


841 名前: デフォルトの名無しさん 投稿日: 03/02/21 15:52
>>840
両方あった方が良い(w


842 名前: デフォルトの名無しさん 投稿日: 03/02/21 20:14
>>834
勘違いしている馬鹿発見。


843 名前: デフォルトの名無しさん 投稿日: 03/02/25 22:32
低レベルな質問で恐縮ですが
VC7にSTLportを導入した、つもりなんですが
どうも上手くいっていないみたいです。

ちゃんとSTLportが使われているかチェックする方法はないですか?

インクルードディレクトリを切り替えてlistの性能比較とかしても差がないし、
iostreamもSTLport版を使うようにし他場合、
#define _STLP_USE_DYNAMIC_LIB してできた実行ファイルを
Dependency Walkerで調べたらstlport_vc745.dllが表示されると
思っていたんですが、表示されませんでした。思い違いでしょうか?
インストールが上手くいっていないだけですか?


844 名前: デフォルトの名無しさん 投稿日: 03/02/25 22:37
>>843
std の変わりに _STL ネームスペースを使って正常にコンパイル
できるかどうかチェックする。


845 名前: 843 投稿日: 03/02/25 22:50
>>844
コンパイルできませんでした(泣
導入からやり直します。ありがとうございました。


846 名前: デフォルトの名無しさん 投稿日: 03/02/25 22:58
>>845
SGI系のアダプタである _STL::compose1 とか _STL::compose2 が
コンパイルできるか確かめてみる方法もあるよ。


847 名前: デフォルトの名無しさん 投稿日: 03/02/26 00:00
std::vector x(10);
for(int i=0;i<10;++i) cin >> x[i];

を for で回さないでなんか algorithm 使って出来ないですかね?

std::vector x(10);
std::transform(x.begin(), x.end(), x.begin(), bind1st(std::mem_fun(&std::istream::operator>>), &std::cin));

で逝けるかなぁと思ったんですけど、
no matching function for call to `mem_fun(<unknown type>)'
と gcc-3.2.1 に言われてしまって…
まぁ完全に趣味なんで別に for で回せばいいんですけどね。


848 名前: デフォルトの名無しさん 投稿日: 03/02/26 00:04
>>847
#include <iterator>
std::copy_n( std::istream_iterator<T>(cin), x.size(), x.begin() );


849 名前: 848 投稿日: 03/02/26 00:08
って、copy_n ってもしかしたらSGI拡張だったかも…。


850 名前: デフォルトの名無しさん 投稿日: 03/02/26 00:10
>>848
やってみたけど11個数字を入れないと終了しないよ。
STLport。


851 名前: デフォルトの名無しさん 投稿日: 03/02/26 00:16
>>847
多分それがだめなのは、operator>>の戻り値型がstd::istreamだから
だろう。


852 名前: デフォルトの名無しさん 投稿日: 03/02/26 00:22
>>847
ファンクタを作ったらだめかい?

template <typename T>
struct input {
T operator()(T& t) {
std::cin >> t;
}
};

int main()
{
std::vector<int> x(10);
std::transform(x.begin(), x.end(), x.begin(), input<int>());
std::copy(x.begin(), x.end(), std::ostream_iterator<int>(std::cout, " "));
}


853 名前: 848 投稿日: 03/02/26 00:24
>>850
おー、ほんとだ。istream_iterator って operator* じゃなくて
コンストラクタと operator++ のタイミングで読まれるのか。使いにくいな。


854 名前: デフォルトの名無しさん 投稿日: 03/02/26 00:24
スマソちょっと修正。

template <typename T>
struct Input {
T operator()(T& t) {
std::cin >> t;
return t;
}
};


855 名前: デフォルトの名無しさん 投稿日: 03/02/26 01:11
入力にtransformはねぇだろ。

template< typename T >
struct input_from_cin
{
 T operator () ()
 {
  T temp;
  cin >> temp;
  return temp;
 }
};
int main()
{
 vector< int > v;
 generate_n( back_inserter( v ) , 10 , input_from_cin< int >() );

 copy( v.begin() , v.end()
    , ostream_iterator< int >( cout , " " ) );
}



856 名前: 847 投稿日: 03/02/26 02:02
なるほど、皆さんありがとです。

>>848
copy_n は知らなんだです。gccのSTLにはあるみたいなんで良さそうですね。
でも確かに >>853 のような事に

>>851
それだと <unknown type> なんですか?そもそもこのエラーメッセージが良く分からんっす。
ちゃんと iostream は include してるから未知って事は無いと思うんですが…

>>852
まぁもちろんファンクタ作ればいいんですが、なんとなく一行野郎で行きたかったんで…

>>855
そうなんですが、一行野郎を目指したら個数を指定する為に無理矢理行き着いたのが
transform でして…可読性はゼロですけどね(w


857 名前: デフォルトの名無しさん 投稿日: 03/02/26 02:37
for_each( v.begin(), v.end(), cin >> boost::lambda::_1 );
とか言ってみる。


858 名前: デフォルトの名無しさん 投稿日: 03/02/26 02:41
>>857
(・∀・)ソレダ!!


859 名前: 847 投稿日: 03/02/26 03:00
>>857
基本を忘れてますた…(w
# 基本か?


860 名前: デフォルトの名無しさん 投稿日: 03/02/26 19:14
lambdaはなぁ・・・。


861 名前: デフォルトの名無しさん 投稿日: 03/02/26 21:34
どうしてもランバダと読んでしまう。


862 名前: デフォルトの名無しさん 投稿日: 03/02/26 22:03
ランバダ算法騎士団


863 名前: tantei 投稿日: 03/02/26 22:05
★あなたのお悩み解決致します!!
●浮気素行調査
彼氏、彼女、妻、夫の浮気を調査致します!!
●盗聴器盗撮機発見
あなたの部屋に誰かが仕掛けているかも!!
●行方調査
行方不明になっている家族の消息を調査致します!!
●電話番号から住所割り出し
一般電話、携帯から住所を割り出し致します!!
●ストーカー対策
社会問題ともなっているストーカーを撃退致します!!
その他人生相談からどんなお悩みでも解決いたします!!
 直通  090−8505−3086
URL  http://www.h5.dion.ne.jp/~grobal/
メール  hentaimtt@k9.dion.ne.jp
   グローバル探偵事務局 




864 名前: デフォルトの名無しさん 投稿日: 03/02/27 07:58
★あなたのお悩み解決致します!!
●浮気素行調査
VB、JAVA、C#、COBOLの浮気を調査致します!!
●トロイ、ウィルス発見
あなたのプログラムに誰かが仕掛けているかも!!
●行方調査
行方不明になっている変数の消息を調査致します!!
●関数名からアドレス割り出し
.dll、.objからアドレスを割り出し致します!!
●バグ対策
社会問題ともなっているバグを撃退致します!!
その他設計相談からどんなお悩みでも解決いたします!!
 直通  http://pc2.2ch.net/tech/
URL  http://www.2ch.net/
メール  2ch@2ch.net
   2ちゃんねるプログラム板 




865 名前: STL初心者 投稿日: 03/02/27 13:40
vector<bool> は使うな という話を小耳にはさんだのですが、ほんとうでしょうか?


866 名前: デフォルトの名無しさん 投稿日: 03/02/27 13:55
boolのvectorとして使うつもりならば本当です



867 名前: デフォルトの名無しさん 投稿日: 03/02/27 14:24
>>865
std::vector<bool>は過去の実装の遺物です。
固定でもよければstd::bitset、可変長が必要ならboost::dynamic_bitset
を使いましょう。


868 名前: デフォルトの名無しさん 投稿日: 03/02/27 16:41
別に使ってもいいと思うよ。
ただし普通のvectorだと思って使うと細かいところで問題が起こる。
あと1要素が1bitで実装されてる保証はない。


869 名前: デフォルトの名無しさん 投稿日: 03/02/27 16:52
>>865
bool型へのポインタが取得できません。


870 名前: STL初心者 投稿日: 03/02/27 16:54
>>867
固定長じゃないんですよー
>可変長が必要ならboost::dynamic_bitset
情報どもです。あとで調べます。
>>868
>ただし普通のvectorだと思って使うと細かいところで問題が起こる。
「細かいところ」って具体的にどんなことなんでしょう?
ビットにパックされているために bool *p = &vecBool[x]; とかができないとか?
push_back(), insert(), erase() と 値の参照、設定さえできればよいのだが
このあたりのことを詳しく説明したドキュメントってどこかにないのかなぁ
それともSTLのソースを読むしかないの?


871 名前: STL初心者 投稿日: 03/02/27 17:03
VC++6.0 を使っているのですが、ソースを読んだり、デバッガでトレースしてみたところ
vector<bool> は1要素を1ビットで表現するという特別な処理をしているようには見えませんでした。
ということは VC++6.0 であれば vector<bool> を使っても問題ないと理解してよろしいのでしょうか?


872 名前: デフォルトの名無しさん 投稿日: 03/02/27 17:06
>>871
使うコンパイラに関係なくstd::vector<bool>を使っても問題ないが、
メンバ関数が返す値はboolへのリファレンスでなくてプロキシである
ことを知っておく必要がある。
>>870さんも言っているように、
bool* p = &vecBool[x]; のようなコードがコンパイルできない。


873 名前: デフォルトの名無しさん 投稿日: 03/02/27 17:09
>>870
> ビットにパックされているために bool *p = &vecBool[x]; とかができないとか?
当たり。できません。
んでもって、これができないモノは正確には「コンテナではない」んだそうです。
よって「vector<bool>はSTLコンテナではない」が成り立つとかなんとか。

なんとなく心配なら、deque<bool>を代用品に選んどくのもいいかも。


874 名前: デフォルトの名無しさん 投稿日: 03/02/27 18:33
>>871
例えばVC++6 ProのSP5なら、<vector>の245行目以下で
boolをunsigned intにパックしてるが。


875 名前: STL初心者 投稿日: 03/02/27 19:16
>>874
あれっ、ほんとだ。
でも vector<bool> vb; と宣言し vb.push_back(true); を実行しても
class vector<_Bool, _Bool_allocator> が利用されていないように
見えるが・・・


876 名前: STL初心者 投稿日: 03/02/27 19:19
それに VC++6.0 で
vector<bool> vb;
vb.push_back(true);
bool *pb = &vb[0];
をコンパイル実行してみると、問題ないようだぜ。
パックするには何かおまじないがいるのかな?


877 名前: デフォルトの名無しさん 投稿日: 03/02/27 20:24
std::vector<bool>で
std::vector<bool, std::allocator<bool> >か、
bool専用のアロケータが使われるかは処理系依存で
さらにbool専用のアロケータの名前も規定されてない


878 名前: デフォルトの名無しさん 投稿日: 03/03/01 23:41
VC.netで、boostのコンパイルがうまくできません。
bjamとかって標準のインストールパスにしか対応していないのですか?


879 名前: デフォルトの名無しさん 投稿日: 03/03/02 21:17
最近STL使い始めた初心者です。
グローバルでSTL宣言すると12バイトのメモリリークが起きるようなんですが、
これの解消法ってどうすればいいんですか?


880 名前: デフォルトの名無しさん 投稿日: 03/03/02 21:40
>>879
よーわからんけど、「12バイトのメモリリーク」 はどうやって確かめたの?


881 名前: デフォルトの名無しさん 投稿日: 03/03/03 00:01
template <class charT>
const charT *mes()
{
return "message";
}

質問です
mes<char>(); //はOK
mes<wchar_t>(); //だめ、理由はわかってます。でもどうしたらいいのでしょうか


882 名前: デフォルトの名無しさん 投稿日: 03/03/03 00:07
return TEXT("message"); // ←こうかもしれない。



883 名前: デフォルトの名無しさん 投稿日: 03/03/03 00:08
>>881
template <>
const wchart_t *mes()
{
return L"message";
}


884 名前: デフォルトの名無しさん 投稿日: 03/03/03 00:34
>>883
ああ、そりゃそうですね・・・
ども


885 名前: 879 投稿日: 03/03/03 21:24
>>880
あ、すみません、説明不足でした。

list<int> hoge;
という風にグローバルで宣言して、そのまま終了すると
12バイト漏れる、ということで。

メモリリークを調べるのには
_CrtDumpMemoryLeaks()
を使いました。


886 名前: デフォルトの名無しさん 投稿日: 03/03/03 21:37
グローバルに静的に確保されたオブジェクトにリークもクソもないと思うが。



887 名前: デフォルトの名無しさん 投稿日: 03/03/03 21:38
グローバルで宣言したクラスの
コンストラクタとデストラクタが呼び出されるタイミングと
_CrtDumpMemoryLeaksが呼び出されるタイミングを考えてみろ


888 名前: デフォルトの名無しさん 投稿日: 03/03/03 23:29
VC6だとlocaleでリーク起こすけど
using namespace std;
try{
locale::global(locale("2ch"));
} catch(exception &e) {}
これでリーク起こす。


889 名前: デフォルトの名無しさん 投稿日: 03/03/04 00:06
>>888
VC6はC Runtimeのソース付いてるから直せるぞ


890 名前: 879 投稿日: 03/03/04 21:01
>>887
あー・・・。
気付きませんでした。どうもです。


891 名前: デフォルトの名無しさん 投稿日: 03/03/05 08:35
VC6の出力が \ になるのですが、なぜに?

#include<sstream>
#include<string>
#include<iostream>
#include<vector>
using namespace std;

int main()
{
basic_stringstream<wchar_t> S;

const char c[]="圭";
size_t size = mbstowcs(NULL,c,0);
vector<wchar_t> tmp(size+1);
wstring data;
mbstowcs(const_cast<wchar_t*>( &tmp[0] ),c,size);
*(static_cast<volatile wchar_t*>( &tmp[0] )+size) = L'\0';
S << &tmp[0];
S >> data;
wcout << data;// VC6だと\, VC.NETだと圭
}


892 名前: デフォルトの名無しさん 投稿日: 03/03/05 11:14
まず、setlocaleしる。

> mbstowcs(const_cast<wchar_t*>( &tmp[0] ),c,size);
> *(static_cast<volatile wchar_t*>( &tmp[0] )+size) = L'\0';
ここのキャストは要らないと思うんだけど。
 mbstowcs(&tmp[0],c,size);
 tmp.back() = L'\0';
これでいいはず。

んで、試してみたけど。
 wcout << &tmp[0] << endl;// 「圭」
 wcout << S.str() << endl;// 「圭」
 wcout << data << endl;// なにもでない

> S >> data
こいつがうまくいかないみたい。
原因は追いきれなかった。


893 名前: デフォルトの名無しさん 投稿日: 03/03/05 11:29
VC6.0です(STL?)。

Redo/Undoの機能をつけるために
ポインタをポインタの配列で管理しようとしているのですが

配列のサイズを決めて新しい要素を入れると
古いものから順に消していってくれるような都合のいい
クラステンプレートってないですか?


894 名前: デフォルトの名無しさん 投稿日: 03/03/05 11:35
>>892

>setlocale(LC_ALL,"Japanese");を忘れてました。

ライブラリ側の問題ぽいので
S.str()で回避して使っていこうと思います。

ありがとうございました。



895 名前: デフォルトの名無しさん 投稿日: 03/03/05 11:37
>>893
std::queueのラッパーでいいんじゃねーの。


896 名前: デフォルトの名無しさん 投稿日: 03/03/05 11:59
キュー、っつーかリングバッファだな。
リングバッファを実現するコンテナアダプタはSTLの解説で幾つか見たことあるが、
公開されてるものはない気がするから自分で作ったほうがはやそう。



897 名前: 893 投稿日: 03/03/05 12:16
>>895, 896
どっかから参考になりそうなものを探して自作することにします。
ありがとうございました。



898 名前: デフォルトの名無しさん 投稿日: 03/03/05 12:37
FIFOバッファだからdeque使えばいいだけの話じゃないの?


899 名前:   投稿日: 03/03/05 15:38
stlport_vc6.dll を stlport.dll にリネームして使いたいと思います。
方法がわかる方はいらっしゃいませんか?
いらっしゃいましたら、方法を教えてください。

まさか stlport_vc6.lib をバイナリ・エディット?


900 名前: デフォルトの名無しさん 投稿日: 03/03/05 17:56
G++でwcoutを使うにはどうすればよいのでしょうか?



901 名前: デフォルトの名無しさん 投稿日: 03/03/05 18:21
std::vector<std::string> a;
ってやっちゃだめなの?



902 名前: デフォルトの名無しさん 投稿日: 03/03/05 18:43
>>901
当然良し。


903 名前: デフォルトの名無しさん 投稿日: 03/03/05 19:08
vector<bool>を使ったらだめな理由がわかりません。
つーか便利だよ
vector<char>だと8倍メモリくうし

bool *p=&vec[0];
これができないとなんでだめなんだよー



904 名前: デフォルトの名無しさん 投稿日: 03/03/05 19:16
http://www.agemasukudasai.com/bloom/


905 名前: デフォルトの名無しさん 投稿日: 03/03/05 19:23
>>902
vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど
なんかあやしいきもするんですが・・・


906 名前: デフォルトの名無しさん 投稿日: 03/03/05 19:25
>vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど
VC6発見

#pragma warning (disable : 4786)
ソースの先頭に置いときなさい


907 名前: デフォルトの名無しさん 投稿日: 03/03/05 19:30
>>906
はーい


908 名前: デフォルトの名無しさん 投稿日: 03/03/05 19:35
>>885
ちょいと遅レスだがたしかSTLは効率のために内部にちょびっと
つねにメモリもってるらしいよ。どっかの過去ログにあるはず。
で、どっかで何かをdefineすればなくなるがパフォーマンス
悪くなる。(ってことなのかな?的外れだったらスマソ)


909 名前: デフォルトの名無しさん 投稿日: 03/03/05 21:04
>>908
そういうのはメモリリークとは言わないけどね。


910 名前: デフォルトの名無しさん 投稿日: 03/03/05 21:14
>>908
メモリプールといいます。そういうのは。


911 名前: デフォルトの名無しさん 投稿日: 03/03/06 02:33
コンテナとかはstlport使ってるんですが、
stlportのiostreamを使う利点はあるのですか?
static-linkだと容量でかくなるし
もしたいした違いがないならコンパイルせずに
標準のiostream使おうと思うので
教えてください


912 名前: デフォルトの名無しさん 投稿日: 03/03/06 12:01
STLportのCVSにWinCVS(or TortoiseCVS)でアクセスできませんか?


913 名前: 912 投稿日: 03/03/06 12:02
もちろん、読み取りだけで十分です。


914 名前: デフォルトの名無しさん 投稿日: 03/03/07 00:22
>>900
glibc のバージョンが古いと思われ。
glibc-2.2(だったかな?)以降が入ってる環境を使うべし。


915 名前: デフォルトの名無しさん 投稿日: 03/03/07 05:41
 set<string> coll;
という変数宣言がされている状況で、
 for_each(istream_iterator<string>(cin), istream_iterator<string>(),
      coll.insert);
としたいんだけど、gcc-2.95.3 では
no matching function for call to `for_each (istream_iterator<string>, istream_iterator<string>, {unknown type})'
とエラーになってしまう…
(本当はもっとエラーメッセージが長いけど、適宜省略)

プロ言C++第3版の13.2.3を見ると「テンプレート引数としては…メンバに対す
る多重定義されていないポインタなどが使える」とあって、これからすると、
このset<string>::insertみたいな多重定義されているメンバ関数はテンプレート
引数としては渡せないような気もするんだけど、これって本当?


916 名前: 915 投稿日: 03/03/07 05:42
やりたいことは、下記のような関数オブジェクトInserterを作って、
 template<class Collection>class Inserter {
  private:
     Collection *container;
  public:
     Inserter(Collection &c) { container = &c; }

     void operator()(const typename Collection::value_type &v)
     {
         (*container).insert(v);
     }
 };
coll.insert の代わりに Inserter< set<string> >(coll) と書けば
できたけど、なんか納得いかないというか、イマイチGenericじゃない
気がしてる。実際、for_eachを手で展開して
 istream_iterator<string> in(cin);
 while (in != istream_iterator<string>())
     coll.insert(*in++);
とすれば動くだけに、なんかクヤしい。
なんか良い手ないかしら?



917 名前: デフォルトの名無しさん 投稿日: 03/03/07 06:16
std::insert_iterator, std::inserterというのがあるわけだが。


918 名前: デフォルトの名無しさん 投稿日: 03/03/07 11:39
#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
std::set<std::string> sset;
std::copy(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::inserter(sset,sset.begin()));

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

return 0;
}



919 名前: デフォルトの名無しさん 投稿日: 03/03/07 12:26
>>916

std::set<std::string> coll;
std::copy(std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::insert_iterator<std::set<std::string> >(coll, coll.begin()));

std::setに関するstd::insert_iterator()の定義はちょっと面白いようになっている。
c.insert(p, t) を呼び出すわけだが、std::setではinsertのメンバ関数は探索位置を
指定する必要はない。だが互換性のためにヒントとしてパラメータを持っている。
そのためstd::insert_iterator()が使えるのである。


920 名前: デフォルトの名無しさん 投稿日: 03/03/07 12:31
std::back_inserter()は使えない。なぜならstd::setはpush_back()というメンバ関数を
持たないからだ。


921 名前: デフォルトの名無しさん 投稿日: 03/03/07 18:51
>>918-920
ども。それは分かります。
ただ、915-916 で言いたかったのは、この処理は間違いなく
for_eachイディオムで書ける筈だし、実際マクロならFOR_EACH
の形で書けので、templateでだって可能じゃないのか、916で
やったように、insertをハードコードすることなく、(Scheme
なら lambda を使って簡単に書けるわけだから) C++ でもなにか
方法がある筈じゃないのかってことなんでした。
もっとも 915-916を書いた時点では、自分でも何が気に入ら
なかったのかはっきりしてなかったので、うまく書けませんでした。



922 名前: 915 投稿日: 03/03/07 18:59
で、915で書いた推測は全く見当はずれでした。

3点大きな間違いがあって、まずそもそも「coll.insert」
っていうのは、C++ の文法上許されない表現なので、
template関数の引数には書けません。(^^;
正しい表現は &set<string>:insert となりますが、
この場合、&set<string>:insert だけでなく coll も
別に渡してやる必要がありました。

それから、この場合、coll.insert を渡している場所は
テンプレート引数ではなく、テンプレート関数の通常の
引数なので、くだんのプロ言C++第3版の13.2.3の記述は
そもそも関係ありませんでした。

最後に、ちゃんと確認してみたところ、使っている処理系
(gcc-2.95.3)だと、多重定義されているメンバ関数を
テンプレート引数として渡すことだって可能でした。
(gccの拡張機能?)



923 名前: デフォルトの名無しさん 投稿日: 03/03/07 19:02
で、922で書いたようにcollも渡す必要があるわけで、
mem_fun_refに習って、次のような関数オブジェクトを定義しました。

template<typename ReturnType, typename Class, typename Arg1Type>
class obj_mem_fun1_t : public unary_function<Arg1Type, ReturnType> {
private:
    Class *object;
    ReturnType (Class::*memfun)(Arg1Type);
public:
    explicit obj_mem_fun1_t(Class &o, ReturnType (Class::*mf)(Arg1Type))
        : object(&o), memfun(mf) {}

    void operator()(Arg1Type a1)
    {
        ((*object).*memfun)(a1);
    }
};

template <typename ReturnType, typename Class, typename Arg1Type>
inline obj_mem_fun1_t<ReturnType, Class, Arg1Type>
obj_mem_fun(Class &object, ReturnType (Class::*mf)(Arg1Type))
{
    return obj_mem_fun1_t<ReturnType, Class, Arg1Type>(object, mf);
}



924 名前: 915 投稿日: 03/03/07 19:04
これで、
 for_each(
 istream_iterator<string>(cin),
 istream_iterator<string>(),
   obj_mem_fun(coll, &set<string>::insert));
とすればOKかなと思ったんですが、gcc-2.95.35だと
no matching function for call to `obj_mem_fun (set<string> &, {unknown type})'
となってしまいました…



925 名前: 915 投稿日: 03/03/07 19:07
しかし、テンプレート引数を明示的に指定して
 for_each(
   istream_iterator<string>(cin),
   istream_iterator<string>(),
   obj_mem_fun<
     pair<set<string>::const_iterator, bool>,
     set<string>,
     const set<string>::value_type &
   >(coll, &set<string>::insert));
とすればコンパイルもでき、動作しました。
これで、915-916で思ってたことは、ほぼ満足です。
(テンプレート引数を明示しなければいけないのが
ちょっと残念だけど。)



926 名前: 915 投稿日: 03/03/07 19:12
で、またまた疑問なんですが、のコンパイルエラーは
仕様なんでしょうか、バグなんでしょうか、それとも
未定義な部分(実装上の制限)なんでしょうか?

それから、こういう、オブジェクトに対する呼びだし
obj.message(arg1) を普通の関数呼びだし func(arg1)
の形式に変換する関数アダプタって、標準的にあって
も良さそうな気がするんですが、boost とか、そういう
準標準ライブラリとして、こういうものってないんで
しょうか?



927 名前: 915 投稿日: 03/03/07 19:15
< で、またまた疑問なんですが、のコンパイルエラーは

う、書き間違えました。これは

> で、またまた疑問なんですが、924のコンパイルエラーは

でした。


928 名前: デフォルトの名無しさん 投稿日: 03/03/07 19:51
boostのbindを調べてください


929 名前: デフォルトの名無しさん 投稿日: 03/03/07 19:58
template <typename ReturnType, typename Class, typename Arg1Type,typename Class2>
inline obj_mem_fun1_t<ReturnType, Class, Arg1Type>
obj_mem_fun(Class2 &object, ReturnType (Class::*mf)(Arg1Type))
{
return obj_mem_fun1_t<ReturnType, Class, Arg1Type>(object, mf);
}

こうしたらVC7でとおった



930 名前: デフォルトの名無しさん 投稿日: 03/03/07 21:40
>>926
何がやりたいのかよくわからん


931 名前: 915 投稿日: 03/03/08 07:05
>>928

ドキュメントを読んで下記を試してみたところ、期待通りに
動作しました。
 for_each(
  istream_iterator<string>(cin),
  istream_iterator<string>(),
  boost::bind< pair<set<string>::const_iterator, bool> >(
   boost::mem_fn(&set<string>::insert), boost::ref(coll), _1));
素晴らしいです。どうもありがとうございました。

最初は下記のやり方を試したんですが、こちらの書き方だと、
自作のもっと単純な型に対しては動くんですが、set<string>
に対しては、924 と同様の症状でコンパイルに失敗してしまいました。
 for_each(
  istream_iterator<string>(cin),
  istream_iterator<string>(),
  boost::bind(&set<string>::insert, boost::ref(coll), _1));



932 名前: デフォルトの名無しさん 投稿日: 03/03/08 07:45
>>931
> boost::bind< pair<set<string>::const_iterator, bool> >(
>   boost::mem_fn(&set<string>::insert), boost::ref(coll), _1));
その使い方だったらboost持ち出すまでもなく
bind1st<...>( mem_fun(&set<string>::insert), &coll )
でよくない?


933 名前: 915 投稿日: 03/03/08 09:53
>>932
なるほど。言われてみれば確かにその通りです。
mem_funを使って
 for_each(
   istream_iterator<string>(cin),
   istream_iterator<string>(),
   bind1st(
 mem_fun<
   pair<set<string>::const_iterator, bool>,
   set<string>,
   const set<string>::value_type &
 >(&set<string>::insert),
 &coll));
とするか、あるいはmem_fun_refを使って
 for_each(
   istream_iterator<string>(cin),
   istream_iterator<string>(),
   bind1st(
 mem_fun_ref<上に同じ>(&set<string>::insert),
 coll));
とすれば、うまく行く筈ですね… と思ってやってみたら、
例の「参照への参照」問題が発生して、どちらもコンパイル
エラーになってしまいました…

bind1stが定義する関数オブジェクトの呼びだし時に、
set<string>::insert() の引数型(const string への参照です)
への参照型を使って渡そうとするのが、原因のようです…



934 名前: デフォルトの名無しさん 投稿日: 03/03/08 11:41
うーんgcc3.2.2(MinGW)ではコンパイルに失敗するね。
移し間違えているのかな?

std::set<std::string> coll;
std::for_each(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
boost::bind<std::pair<std::set<std::string>::const_iterator, bool> >(
boost::mem_fn(&std::set<std::string>::insert), boost::ref(coll), boost::lambda::_1));

C:/MinGW/boost/set_insert.cpp: In function `int main()':

C:/MinGW/boost/set_insert.cpp:19: no matching function for call to `
mem_fn(<unknown type>)'


935 名前: 915 投稿日: 03/03/08 12:16
あれれ、unknown typeになりますか。mem_fn()のテンプレート引数を
明示的に指定するとどうでしょう?
set<string> coll;
for_each(istream_iterator<string>(cin), istream_iterator<string>(),
  boost::bind< pair<set<string>::const_iterator, bool> >(
    boost::mem_fn<
      pair<set<string>::const_iterator, bool>,
      set<string>,
      const set<string>::value_type &
    >(&set<string>::insert), boost::ref(coll), _1));
手元の環境だと、この場合、bind()の方のテンプレート引数は
省略可能になります。



936 名前: デフォルトの名無しさん 投稿日: 03/03/08 12:50
>>935
さらに強烈なエラーが出てきました。

C:/mingw/include/boost/bind.hpp: In member function `R boost::_bi::list2<A1,
A2>::operator()(boost::_bi::type<R>, F, A&) const [with R =

std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, F =
boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const
std::string&, const std::string*>, bool>, std::set<std::string,
std::less<std::string>, std::allocator<std::string> >, const std::string&>,
A = boost::_bi::list1<const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&>, A1 =
boost::reference_wrapper<std::set<std::string, std::less<std::string>,
std::allocator<std::string> > >, A2 =
boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
> >]':


937 名前: デフォルトの名無しさん 投稿日: 03/03/08 12:52
C:/mingw/include/boost/bind/bind_template.hpp:33:
instantiated from `boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&)
[with A1 = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
F = boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
std::set<std::string, std::less<std::string>, std::allocator<std::string> >, const std::string&>,
L = boost::_bi::list2<boost::reference_wrapper<std::set<std::string, std::less<std::string>, std::allocator<std::string> > >,
boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1> > > >]'
C:/mingw/include/c++/3.2.2/bits/stl_algo.h:157:
instantiated from `_Function std::for_each(_InputIter, _InputIter, _Function)
[with _InputIter = std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>,
_Function = boost::_bi::bind_t<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const std::string*>, bool>,
std::set<std::string, std::less<std::string>, std::allocator<std::string> >, const std::string&>,
boost::_bi::list2<boost::reference_wrapper<std::set<std::string, std::less<std::string>,
std::allocator<std::string> > >, boost::_bi::value<boost::lambda::lambda_functor<boost::lambda::placeholder<1> > > > >]'


938 名前: デフォルトの名無しさん 投稿日: 03/03/08 12:52
C:/MinGW/boost/set_insert.cpp:23: instantiated from here
C:/mingw/include/boost/bind.hpp:233: no match for call to `(
boost::_mfi::mf1<std::pair<std::_Rb_tree_iterator<std::string, const
std::string&, const std::string*>, bool>, std::set<std::string,
std::less<std::string>, std::allocator<std::string> >, const std::string&>)
(std::set<std::string, std::less<std::string>, std::allocator<std::string>
>&, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >&)'
C:/mingw/include/boost/bind/mem_fn_template.hpp:129: candidates are: R
boost::_mfi::mf1<R, T, A1>::operator()(T*, A1) const [with R =
std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, T = std::set<std::string, std::less<std::string>,
std::allocator<std::string> >, A1 = const std::string&]
C:/mingw/include/boost/bind/mem_fn_template.hpp:134: R

boost::_mfi::mf1<R, T, A1>::operator()(U&, A1) const [with U =
std::set<std::string, std::less<std::string>, std::allocator<std::string> >,
R = std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, T = std::set<std::string, std::less<std::string>,
std::allocator<std::string> >, A1 = const std::string&]

C:/mingw/include/boost/bind/mem_fn_template.hpp:139: R
boost::_mfi::mf1<R, T, A1>::operator()(T&, A1) const [with R =
std::pair<std::_Rb_tree_iterator<std::string, const std::string&, const
std::string*>, bool>, T = std::set<std::string, std::less<std::string>,
std::allocator<std::string> >, A1 = const std::string&]

Execution terminated


939 名前: デフォルトの名無しさん 投稿日: 03/03/08 22:05
string文字列中の特定の文字Aを検索し、
その文字以降Bが出現するまでの文字列を抜き出したい場合
どうすればよいですか。

string str(`hoge...`);
string::iterator sp;
string::iterator ep;

sp = find(str.begin(), str.end(), 'A');
ep = find(sp, str.end(), 'B');

で要素位置はわかりますが、これをどう使えば
要素を抜き出せるのか。。。


940 名前: デフォルトの名無しさん 投稿日: 03/03/08 22:22
string str("fawAejkreBf");
string::size_type pos=str.find_first_of('A');
if(pos!=string::npos)
{
pos++;
str=str.substr(pos,str.find_first_of('B',pos)-pos);
}


941 名前: デフォルトの名無しさん 投稿日: 03/03/09 00:25
>>939
string AtoB(sp, ep);


942 名前: デフォルトの名無しさん 投稿日: 03/03/09 01:55
>>936
エラーは no match for call to ですか…
なんかメソッドの signature が違っているくさいですね。
コンパイラというよりは、STL の実装の違いのような気が
するんですが、UNIX系OS上の gcc-3.2.1 では 935で問題
なく通りました。gcc-3.2.1と3.2.2で、STL回りって、
そんなに変わっているんでしょうか。



943 名前: デフォルトの名無しさん 投稿日: 03/03/09 02:24
>>942
原因がわかりました。_1 はてっきり boost::lambda::_1 かと思ってたの
ですが、boost::bind の _1 だったのですね。
無事通りました。ありがとうございます。
gcc3.2.2でも通りました(当たり前ですよね)。

ただ、やはり boost:mem_fn のテンプレート引数を明示的に指定しないと
コンパイル通りません。


944 名前: デフォルトの名無しさん 投稿日: 03/03/09 14:43
>>940
>>941
さま。
ありがとうございます。


945 名前: デフォルトの名無しさん 投稿日: 03/03/11 12:20
std::ofstream ofs("test.bin",std::ios::binary);
int tmp = 12;
ofs << tmp;

こうしても、バイナリ出力にはなりませんよね。
fstream系でバイナリ入出力って無理なんですか?



もひとつ。

template<typename T>
void Hoge(const T& t){ /* 省略 */}

に対して、Tが vector<T> みたいなものだった場合は
別なことをさせたいんですが、特殊化でしょうか。
あくまでvector<T>です。まだ型は完全に
決まってないので、部分特殊化なんでしょうか?
VC6で、どうやればいいんでしょうか……?


946 名前: デフォルトの名無しさん 投稿日: 03/03/11 12:37
>>945
バイナリイメージの出入力なら、std::ios::binary付けたうえで、
reinterpret_cast&read/writeかな。

VC6でふつうに部分特殊化したらエラーになった。
サポートできてないんだっけ?


947 名前: デフォルトの名無しさん 投稿日: 03/03/13 08:24
>>945
部分特殊化というよりは、template関数のpartial ordering。
確かVC6では使えないので、何かトリックを使って頑張るしか無いのでは。


948 名前: デフォルトの名無しさん 投稿日: 03/03/13 17:40
微妙にスレ違いですが、質問お願いします。

stringから、整数や実数に直接入力する方法ってありますでしょうか。
今は下記のようにやっています。
string str = "777";
int c = atoi(str.c_str());

なんていうかstdlib.hをインクルードするのが悔しいというか・・・アホですいません。
ストリームみたいに、stream >> intみたいな感じで可能ならなぁ、と。




949 名前: ヽ(´ー`)ノ 投稿日: 03/03/13 18:00
>>948
boost::lexical_cast 使え…とかそういう話?



950 名前: ヽ(´ー`)ノ 投稿日: 03/03/13 18:03
ミスって投稿しちゃった。こんな感じ。

#include <string>
#include <boost/lexical_cast.hpp>

int main(int argc, char **argv) {
string str = "777";
int c = boost::lexical_cast<int>(str);

return 0;
}


951 名前: 948 投稿日: 03/03/13 18:09
>>950
すごい!

            ・・・・boostってすごい_| ̄|○


λ...........オトシテコヨウ…


と、レスありがとうございました。すいません、環境書かなくて…。
今は腐ったVC++6付属の使ってますが、これを機に移行してみようと思います。


952 名前: デフォルトの名無しさん 投稿日: 03/03/13 18:37
>>951
boost::lexical_castは内部的にstd::stringstreamを使っている。
バラして書けばこんな感じ。簡単だろ。

int main()
{
std::string str("123");
std::stringstream sstr(str);
int i;

sstr >> i;

std::cout << i << std::endl;
}


953 名前: 948 投稿日: 03/03/13 19:16
>>952
す、素敵すぎです!ありがとうございました。
移行はするとしても、当座はこれでしのいでみます。


954 名前: デフォルトの名無しさん 投稿日: 03/03/13 19:24
>>953
ちなみにstd::stringstreamのコンストラクタを起動した直後は書き込み位置
も読み込み位置もゼロになっているようだから、適当にシークして追加する
と良い。本当はstd::ios::pos_typeをstd::coutに出力できない場合もあるんだ
けどね。あくまでも例って事で。

int main()
{
std::string str("123");
std::stringstream sstr(str);
int i, j;
std::ios::pos_type p;

p = sstr.tellg();
std::cout << "read pos = " << p << std::endl;
p = sstr.tellp();
std::cout << "write pos = " << p << std::endl;

sstr.seekp(0, std::ios::end);

sstr << " 456";
sstr.seekg(0, std::ios::beg);
sstr >> i >> j;

std::cout << i << ' ' << j << std::endl;
}


955 名前: デフォルトの名無しさん 投稿日: 03/03/13 19:25
sstr.seekg(0, std::ios::beg);
はいらなかったかな。
C++のストリームはCとは違って読み込みと書き込みのポインタは
別々だからね。


956 名前: 948 投稿日: 03/03/13 22:02
>>954-955
いやはや、コードは言葉より雄弁と言いますか・・・。
分かりやすくて本当にためになりました。ありがとうございました。

読んで置いて良かった・・・正直いうと、こんな使いかたしてましたよ(笑

int main()
{
int i;
std::string str("123");
std::stringstream( str ) >> i;

std::cout << i << std::endl;
}



957 名前: デフォルトの名無しさん 投稿日: 03/03/13 23:13
>>945

#include <vector>

template<typename T>
struct foo {
static void Hoge(const T& t)
{
*****
}
static void Hoge(const std::vector<T>& t)
{
****
}
};

foo<int>::Hoge(0);
foo<int>::Hoge(std::vector<int>());

とかじゃダメなの?



958 名前: 957 投稿日: 03/03/14 00:17
>>945

やっぱ上のじゃ不便だな、ってことで以下...

template <int N> struct foo {
template <class T> static void baka(const T& t) { //hogehoge }
};

template <> struct foo<1> {
template <class T> static void baka(const std::vector<T>& t) { //hogehoge }
};

template <class T> char hage(const std::vector<T>& t);
double hage(...);

template<typename T>
static void Hoge(const T& t) { foo<sizeof(hage(t))>::baka(t); }

void test() {
int a = 3;
std::vector<int> v(8);
Hoge(a);
Hoge(v);
}

ちゃんとディスパッチできたよ。
sizeof(char) < sizeof(double) だと規格のどこに書いてあるのか小一時間(略



959 名前: デフォルトの名無しさん 投稿日: 03/03/14 00:55
>>956
うぉ、こんなやり方でもできるんだな
やっぱ使うのまずいっぽ?

コンストラクタで作ってから、どうなってるんだろ
デバッガで追ってみたけどテンプレートが複雑でいまいちわからん


960 名前: デフォルトの名無しさん 投稿日: 03/03/15 03:43
>>945
ふつうにオーバーロードで
template<typename T>
void Fn(const T&){}

template<typename T>
void Fn(const std::vector<T>&){}

int main(){
Fn(int() );
Fn<int>(std::vector<int>() );//Fn<int> 明示的に型指定
return 0;
}




961 名前: デフォルトの名無しさん 投稿日: 03/03/15 08:32
>>956
の示したコードの使い方、あれでいいんじゃないですか?
あってるよね?


962 名前: 958 投稿日: 03/03/15 10:20
>>960

なるほど<int>と限定した上ではただのオーバーロードに
なるんだね。
複雑にして損したよ


963 名前: 956 投稿日: 03/03/15 21:32
>>959 >>961
自分で書いて置いてなんですが、あってるんですか?
さすがに無理な気がしないでもないです…要するにこういう事ですよね?

#include <iostream>

class B{
public:
void hage(){
std::cout << "Hoge" << std::endl;
}
};

int main(){
B().hage();

return 0;
}

実体はどこに・・・というかうちのコンパイラ(VC++6.0)以外でも通るのだろうか。
詳しい方のご意見をお尋ねしたいところです。ってC++スレの方がいいのかな。


964 名前: デフォルトの名無しさん 投稿日: 03/03/15 21:45
>>963

ん?一時オブジェクトの寿命の問題でしょ
全然問題ないよ


965 名前: 956 投稿日: 03/03/15 22:00
>>964
いやぁ、そうなんですか・・・また一つ勉強になりました。

てっきり、Bコンストラクタのスコープから出た瞬間、
デストラクタが呼ばれるのかと思ってました。
Bコンストラクタ>hage>Bデストラクタは保証されているんですねぇ。

うーん、ダメだ。自分この辺ぐだぐだで・・・再勉強してきます。
レスありがとうございました。


966 名前: デフォルトの名無しさん 投稿日: 03/03/15 23:24
一時オブジェクトってのは非constな参照では受けられないけど
非constなメソッドを呼べるという特殊な存在。
この性質を利用したテクニックもある。
でもこれを多用すると一部の論者に睨まれるという諸刃の剣。



967 名前: デフォルトの名無しさん 投稿日: 03/03/16 00:15
一時オブジェクトって、非constな参照で受けられなかったんだ……。
言われてみると、敢えて受けてみたことはないな。
thx.




968 名前: デフォルトの名無しさん 投稿日: 03/03/16 03:16
>>966
おまけに自分自身を返すメソッドを呼ぶと
非constな参照で受けることが可能になるだけでなく
当然左辺値として扱うことも可能になる。

一時オブジェクトは非constな参照で受けることが
できない/右辺値として扱われるって
仕様はホントにあほらしいんだよなぁ。
そんなんだったら始めからエラーじゃなくて、
ワーニング程度に留めとけっての。


969 名前: デフォルトの名無しさん 投稿日: 03/03/16 13:34
>>960

intと明示的に型指定できるくらいだったらvectorなのか
そうでないのかもわかるだろうから、オーバーロードすら
必要ないんじゃない?



970 名前: デフォルトの名無しさん 投稿日: 03/03/16 16:46
>>969

>>945
を、よめ!!!!!!!!!

ちなみにほかのコンパイラーなら
明示的の指定はいらん



971 名前: デフォルトの名無しさん 投稿日: 03/03/16 16:49
>>963
そういう使い方ならstatic関数にすればいいやん
B::hage(); みたいに


972 名前: デフォルトの名無しさん 投稿日: 03/03/16 17:19
>>970

945の意味するところが『いずれテンパラはある一つの型に決めます』ってなら
<T>の部分を明示するのは抵抗ないだろうけどね。
テンパラになる型が最終的に複数出てくる場合はどうだろう。
と思って957→958という流れになったわけだが



973 名前: デフォルトの名無しさん 投稿日: 03/03/16 17:25
staticにしたらこんなのが通らん

#include<cstdio>

//#define STATIC__
struct FuncOperator
{
#ifdef STATIC__
static void operator () (){ puts("static operator"); }
#else
void operator () (){ puts("Non static operator"); }
#endif
};

int main(){

#ifdef STATIC__

FuncOperator::operator ()();
#else
FuncOperator()();

#endif

return 0;
}


974 名前: デフォルトの名無しさん 投稿日: 03/03/16 18:44
staticなオペレータって蟻なのか?


975 名前: デフォルトの名無しさん 投稿日: 03/03/16 18:51
>>974

為し



976 名前: 945 投稿日: 03/03/17 13:24
>>958さん、ありがとうございます。たしかにうまくいきますね。
で、えぇと……実はHoge()はあるクラスのメンバ関数なんですが、
この場合はどうしたらいいんでしょう?^^;

条件が後出しになって申し訳ありません。詳しく状況を言いますね。
まず、バイナリの入出力を簡便にしてくれるクラスが欲しいのです。
標準だと、こうなりますよね。

ifstream ifs("piyo.dat",ios::binary);
int n;
ifs.read(reinterpret_cast<char*>(&n),sizeof(int));
vector<int> v(n);
ifs.read(reinterpret_cast<char*>(&v[0]),sizeof(int)*n);

これだとあまりにも面倒なのです。不要な指定が多すぎて。

CReadFile rf("piyo.dat");
int n;
rf >> n;
vector<int> v(n);
rf >> v

こういう感じですっきり指定できるラッパークラスを作りたいのです。
出力の方も、同じ要領でやりたいと思ってます。
これで、intだけを入出力したいわけじゃないから、templateで、
ということなんです。
で、VC6固有の(ですよね?)templateヘタレ解析に悩まされてるわけです。
そういうわけですので、>>960さんみたいなやり方は、クラス使用者の
負担になりますので、あんまり意味がないわけです。
>>958さんのやり方みたく、多少機種依存の部分があっても、なんとか
隠蔽できればいいんですけど……。


977 名前: デフォルトの名無しさん 投稿日: 03/03/17 14:47
して、次スレの方は?


978 名前: デフォルトの名無しさん 投稿日: 03/03/17 15:06
>>976
template <class T> void hoge(const T &);
を用意しなければいいのでは

つまり
void hoge(int);//unsigned int,float,なども用意する
template <class T> void hoge(const vector<T> &);

でどうでしょう? あんまり無条件でバイナリ保存できる型なんてそうそうないでしょ?
逆に安全性の面から用意されていないと入出力できないようにしたほうが良いとおもわれ


979 名前: デフォルトの名無しさん 投稿日: 03/03/17 17:42
reinterpret_cast<?>(?)のなにがいやぁーなの
もしながくていやとかぬかしてんのそれなら(char*)キャスト使えば
もし、それでもかっこ悪いとか言うんなら自分でvector<T>専用をつくれば

template<typename T>char* Cast(std::vector<T>& tt)
{return reinterpret_cast<char*>(&tt[0]); }

こんな感じに。
さらにintとunsigned charを使い分けたいなんて我侭もあるんなら

union bit{
int i;
unsigned char bitn[4];
};
std::vector<bit>これで読み込ませればint、
unsigned charの使い分けが一回の作業で実現できよう。
とにかくreinterpret_castぐらいでクラスなんて作ってられない





980 名前: デフォルトの名無しさん 投稿日: 03/03/17 20:22
#define scast static_cast
#define rcast reinterpret_cast
#define ccast const_cast
#define dcast dynamic_cast


981 名前: デフォルトの名無しさん 投稿日: 03/03/17 20:37
template <class T,class U> T scast(const U &u)
{ return static_cast<T>(u); }


982 名前: デフォルトの名無しさん 投稿日: 03/03/17 21:14
>>980
それをやるならここでは、こうでしょ。。
#define Cast(M) reinterpret_cast<char*>(M)



983 名前: デフォルトの名無しさん 投稿日: 03/03/17 21:19
>>981
いみない。結局明示的に指定しなくちゃならんでしょ


984 名前: デフォルトの名無しさん 投稿日: 03/03/17 22:30
http://www.tietew.jp/cppll/archive/1071
キャスト


985 名前: デフォルトの名無しさん 投稿日: 03/03/17 23:06
>>982
char * 型以外に使えないじゃん。


986 名前: デフォルトの名無しさん 投稿日: 03/03/17 23:38
ねえ、早く!



987 名前: スレタイはこれで 投稿日: 03/03/18 02:09
template<typename STL,Boost,Loki,etc>class part2


988 名前: デフォルトの名無しさん 投稿日: 03/03/18 02:56
>>987
<> は化けるのでは?


989 名前: デフォルトの名無しさん 投稿日: 03/03/18 18:10
一応新スレ立てときました。

【C++】template 統合スレ -- Part2
http://pc2.2ch.net/test/read.cgi/tech/1047978546/


990 名前: 投稿日: 03/03/19 06:35
〈〉←これで代用という手がある。


991 名前: デフォルトの名無しさん 投稿日: 03/03/19 20:53
777?


992 名前: デフォルトの名無しさん 投稿日: 03/03/19 22:52
この板では1000ゲットは興味なしですか?


993 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:04
ぬるぽがこのスレに興味を持ったようです。

  ∧_∧
 ( ´∀`)< ぬるぽ


994 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:12
  ∧_∧
 ( ´∀`)< ぼくぬるぽ



995 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:41
もうすぐか…


996 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:42
なにが?


997 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:44
>>996
1000が


998 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:48
 


999 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:49
999


1000 名前: デフォルトの名無しさん 投稿日: 03/03/19 23:49
そんなバカなやり取りしてる間に1000げt


1001 名前: 1001 投稿日: Over 1000 Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。



2ちゃんねるは、ここのサーバを使ってるです。。。