5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

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

【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 初心者なもので、色々と不具合があるかもしれません。
みなさんどうもありがとうございました

217 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)