■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 part23
751 名前:デフォルトの名無しさん :03/10/07 19:47
>>750
749はソースコード上の事だと思はれ。

752 名前:デフォルトの名無しさん :03/10/07 20:07
インライン化された関数じゃなくて、
inline 指定した関数ってことだろ。


753 名前:デフォルトの名無しさん :03/10/07 20:23
>>746
コンテナ毎にどの操作でiteratorが無効になるかちゃんと定義されてる。

754 名前:デフォルトの名無しさん :03/10/07 22:39
>インライン関数のポインタなんか取れないから

何が普通だ どアフォ
templateなんか全然関係ねえんだよ
軽い気持ちでいっぺん氏んでこい

755 名前:704@お勉強中 :03/10/07 23:08
>>726 丁寧に書き込んで頂いて有難うございます。
Effective-STL買ってきて読み始めました。
ついでにプログラミング言語C++も買いました。
分厚くて1部分しか読んでないですが、関数オブジェクトの方が速いと書いてありました・・・
非業界人がC++使いこなせるようになるのでしょうか不安です^^;

756 名前:デフォルトの名無しさん :03/10/07 23:50
>>755
非業界人の方が自由に使いこなせる。

業界人で組み込み系の部署につかされたら悲惨。iostremは使わないわ
変数の命名はハンガリアン記法でなくて会社独特の物だし、ヘッダファイ
ルもカスタマイズされたものだけだし、C++でなくてCで十分だと思える。

そうでなくてアプリを作る部署ならC++も生きてくるが、規格書作るのが
大変。クラスの定義は一番初めに決めなければならないし、そこから
子クラスを導出するデザインも全部決めなければならない。(UML)
boostはもちろん使えない。STLでも使えるのはstd::vectorのみに限られて
いたり、よくてstd::mapやstd::multimap止まり。

ファンクタはアルゴリズムから呼び出すのだけど、これも規格書の段階
で決めておかないと使用禁止。本当にうぜーわ。数人〜数十人でcvs
使うからそれくらい厳格にしておかないとバグ探すのが大変なんだよ。

#教訓。C++を「学ぶ」のと「飯の種にする」のとでは行って帰ってくるほどの
#差がある。

757 名前:デフォルトの名無しさん :03/10/07 23:53
あ、もう一つね。

export template に対応したC++処理系は今の所仕事では使っていない。
そのためtemplateは複数の人で開発するのにほとんど無意味。従って
重要なテンプレートはすべてヘッダファイル入り。C++にしてからヘッダ
ファイルを作るのにかかる時間がすごく延びた気がする。

758 名前:デフォルトの名無しさん :03/10/08 00:08
>>755
大丈夫、業界人だって使いこなせてない香具師が多いから。

759 名前:デフォルトの名無しさん :03/10/08 00:43
>>756
会社やプロジェクトによりけりだって。俺のトコロは STL も Boost も遠慮無く使う方針で
行ってる。

変数の寿命管理は原則としてスマートポインタ必須で生 delete 禁止。

760 名前:デフォルトの名無しさん :03/10/08 00:45
スマートポインタとは古いな。時代はGCだろ。

761 名前:デフォルトの名無しさん :03/10/08 01:07
C++にeclipseのようにgetterとsetterを自動で書いてくれるツールはありませんか?
お勧めの物を教えて下さい。

762 名前:デフォルトの名無しさん :03/10/08 01:51
>>761
マクロプログラミング

763 名前:デフォルトの名無しさん :03/10/08 21:28
>>761
全データメンバに洩れなくgetter/setterがついてるコードでも書く気か?
情報隠蔽の理念と根本的に対立する思想だな

764 名前:デフォルトの名無しさん :03/10/08 21:40
>>763
eclipseの場合は変数ごとにgetter,setterのチェックボックスのツリーが出てきて
自由にgetterとsetterを追加削除できるんです。
getterだけ追加してreadonlyにする事も簡単に出来ます

765 名前:デフォルトの名無しさん :03/10/08 23:00
C++ではset/getなんてしないよ。
コンストラクタ以外のメンバは全て全部privateにして、
通信する相手は友達だけにする。

のは冗談としても、普通に構造体で直にアクセスさせることも
多い。set/getなんてまどろっこしいことはあまりやらない。

766 名前:デフォルトの名無しさん :03/10/08 23:27
C++でPascalのようなbegin/endが使えるようになるツールはありませんか?
C++でAPLのように行列の計算が入出力込みで1行で書けるツールはありませんか?
C++でCOBOLのようにPERFORM THRUが使えるツールはありませんか?
C++でJavaのようにGCが使えるツールはありませんか?

てめえで作れつーの

767 名前:デフォルトの名無しさん :03/10/09 00:50
>>765
C++をbetter Cとして使うのならそれでいいのかもしれませんが、
私はOOPLとしてC++を使っているので。
setterとgetterの利点についてはこの辺読んでください。
http://www.muraoka.info.waseda.ac.jp/~fukumori/oo/why_use_getters_and_setters_j.html

>>766
あなたは勘違いしてると思うんですが、setter,getterはJava特有の物ではありません。
OOPLならばどんな言語でもsetterとgetterは書くはずです。C++も無論そうです。
関係ありませんが、C++でGCが使えるライブラリは既に存在しますし私も利用しています。

768 名前:デフォルトの名無しさん :03/10/09 00:58
ちょっと面倒だがそれくらい自分で書いたほうがいいかも。
ツール使う方がかえって面倒になることがある(例:VC++のメンバの追加ダイアログ)

769 名前:デフォルトの名無しさん :03/10/09 01:05
YAGNI,YAGNI、と云いつつ、広域置換を使う俺。

770 名前:デフォルトの名無しさん :03/10/09 01:12
>>761
ない

771 名前:デフォルトの名無しさん :03/10/09 01:19
どうも無さそうですね。仕方ないんで自作して使います。

772 名前:デフォルトの名無しさん :03/10/09 01:38
>>767
知ってるOOPLの範囲狭すぎ


773 名前:デフォルトの名無しさん :03/10/09 01:39
>>772
propertyの存在も知っています。
結局propertyにしてもgetとsetはありますよね。

774 名前:デフォルトの名無しさん :03/10/09 01:46
>>767
getter/setterが必須だと思うのなら手間を惜しむな。
#本来全く考えなしにgetter/setterを書くべきではない。そうであるなら大した手間ではないだろう。

どうしても手間を惜しみたいならeclipseで書け。
まさかeclipseではJavaしか開発できないなんて思っているわけじゃないだろ?

775 名前:デフォルトの名無しさん :03/10/09 01:48
>>774
CDTにプロパティ自動生成があればeclipse使うんですが、
JDTにしか無いんですよね。リファクタリング機能にしてもプロパティ自動生成にしても。

776 名前:デフォルトの名無しさん :03/10/09 01:50
>>773
…。

では、setter/getterなんて本来必要なくて、直接そのオブジェクト自身にIOまで行わせるべきだという主張の存在は?
(クラス構造が静的だと辛いけど、後付け可能なら無茶な話じゃ無い)

777 名前:デフォルトの名無しさん :03/10/09 01:51
>>776
そもそも動的型付け以前に、
C++のようなプリミティブ型が存在する言語にそのような理想論を持ち込まれても困るんですが。

778 名前:デフォルトの名無しさん :03/10/09 01:52
Java厨にはかまうな。放置しろ。

779 名前:デフォルトの名無しさん :03/10/09 01:53
>>778
なんでそこでJava厨が出てくるのか貴方の頭の構造が全く理解不能です。

780 名前:デフォルトの名無しさん :03/10/09 02:01
「OOPLとしてC++を使っている」、と、
「Javaの言語機能という制限上で培われた流儀のOOPをC++でも行おうとしている」、の微妙な違いというか

781 名前:デフォルトの名無しさん :03/10/09 02:13
OOPLならば(>>767)って言うくらいだから
Java/C++/C#/ObjectPascal etcの「なんちゃってOO言語」じゃなく
SmalltalkとかEifellとかの純粋なOOPLの事を言ってるんだろうね。

782 名前:デフォルトの名無しさん :03/10/09 02:24
こういう生物をJava厨って呼ぶのか。

783 名前:704@お勉強中 :03/10/09 03:17
えー、本を読んでいるとメンバ変数はprivateに入れろと書かれていますが、
やっぱり時と場合によってpublicにする場合もあると言う議論でしょうか?

このレベルだと翻訳して貰わないと良く理解できません。

784 名前:デフォルトの名無しさん :03/10/09 05:08
話しそれて申し訳ないけど、外からは使えないのに
記述的に公開しているprivateって概念は、
糞だと思うが仕方ないんだよな…

785 名前:デフォルトの名無しさん :03/10/09 07:30
>>767
> http://www.muraoka.info.waseda.ac.jp/~fukumori/oo/why_use_getters_and_setters_j.html
は、「データメンバをpublicにせずに、代わりにgetter/setterを
使うことの利点」 だろ?「privateメンバには対応するgetter/setterを
設ける」 という習慣はやめた方がいい。

Why getter and setter methods are evil
 http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html
でも読んでこい。

786 名前:デフォルトの名無しさん :03/10/09 09:00
>「privateメンバには対応するgetter/setterを設ける」
って誰が言ってるんだ?>>763

787 名前:デフォルトの名無しさん :03/10/09 10:14
>>785 代りにどうしたらいいの?

788 名前:デフォルトの名無しさん :03/10/09 11:53
>>784
pimpl知らないの?

789 名前:デフォルトの名無しさん :03/10/09 13:51
>>770
すてき

790 名前:デフォルトの名無しさん :03/10/09 23:15
>>786
761。
ツール=機械と読んだ。
自動=機械的に=人情は関係なしと読んだ。
privateはお前が言い出した妄想。

791 名前:デフォルトの名無しさん :03/10/10 21:46
以降の流れについて説明する「まとまった処理についてのコメント」と、
「ちょっとした補足コメント」を区別したいのですが、これ!という方法があったらぜひ教えてください。

■気分的にはこんな感じです
//まとまった処理についてのコメント{
 //ちょっとした補足コメント
 //ちょっとした補足コメント


■↓だと「「ちょっとした補足コメント」の方が、スペースや位置的書きづらくて…

  //これから、まとまった処理が始まるよ

  int hoge = 7; //hogeについての、ちょっとした補足だよ

■↓だと、両者の区別がいまいちしづらくて…

  //これから、まとまった処理が始まるよ

  //hogeについての、ちょっとした補足だよ
  int hoge = 7;

792 名前:デフォルトの名無しさん :03/10/10 21:48
/////////////////////////////////////////////////////////////
//まとまった処理についてのコメント
/////////////////////////////////////////////////////////////
hage::hage()
{

//hogeについての、ちょっとした補足だよ
int hoge = 7;






}

793 名前:791 :03/10/10 21:58
>>792
にゃるほど!ちょっと大人しめにしてマクロ登録しますた
レス感謝!ありがとうございやした

794 名前:791 :03/10/10 22:00
いやまてよ、「まとまった処理は関数にしろや」というアイロニーも
込められてるっぽいな。お気遣いありがとう。

795 名前:デフォルトの名無しさん :03/10/10 22:29
/**
* まとまった処理についてのコメント
* @param
* @return
*/

796 名前:デフォルトの名無しさん :03/10/10 23:30
>>784
つかう場面がわからない君がクソだと思うぞ

797 名前:デフォルトの名無しさん :03/10/10 23:42
>>796
誤爆?

798 名前:デフォルトの名無しさん :03/10/11 07:52
>>797
正爆

799 名前:デフォルトの名無しさん :03/10/11 10:50
最近ようやく入門書を読み終えて関数やクラスの使い方が
わかってきた初心者ですが、質問させてください。

入門書やWeb上に文字列を扱うクラスなどはよく載ってるんですが、
それ以外に、自分のしたい事が実現できるクラスはみなさんどーやって
探してるんでしょうか?ネット上を徘徊したり本を読み漁って、
偶然そのクラスが使われているサンプルを見つけるんでしょうか・・・?
そうだとしても、最初に使った人はどーやって使い方を覚えたのか気になります。
C++のクラス一覧みたいなものがどこかにあったら教えてください。

800 名前:デフォルトの名無しさん :03/10/11 11:14
>>799
意味分からんw

クラスライブラリのリンク集ならこのスレの始めに
あるぞ。使い方とか、最低限ドキュメントに目を通してから
言えよ。

801 名前:デフォルトの名無しさん :03/10/11 11:24
>>799
無いクラスは作るものだ。

802 名前:デフォルトの名無しさん :03/10/11 11:58
>>799
使い方というか、アルゴリズムの解説してる本なら沢山ある。
アルゴリズムの解説を読んで、クラスは自分で書く。

あと、有名なアルゴリズムなら大体誰かがコード化してる。
問題は大半が英語なのと、C言語(非OOP)で書かれてる事が多いこと。

C++ のクラス一覧は MSDN でも嫁。


803 名前:デフォルトの名無しさん :03/10/11 13:37
>>802
>C言語(非OOP)
洩れの知る限りCで書かれたライブラリの多くは充分にOOPだが何か?
C++で書かれたMFCなんぞよりもずっとマシだったりする

804 名前:デフォルトの名無しさん :03/10/11 14:05
>>803
ああ、まあ、ライブラリと呼べるようなまともな奴は確かに OOP してるし、
MFC の方がよっぽど糞だけど。

逆に俺は C で OOP してるソース見ると、
素直に C++ 使えよというやるせない気持ちになる。


805 名前:デフォルトの名無しさん :03/10/11 14:09
char *buf=new char[100];
などという感じで確保したメモリを解放するときは、
delete buf; と delete[] buf; のどちらを使えばいいのでしょうか。
とりあえずコンパイルはどちらも通るんですが。

806 名前:デフォルトの名無しさん :03/10/11 14:12
入門書を穴が開くほど読め。
話はそれからだ。

807 名前:デフォルトの名無しさん :03/10/11 14:22
>>805
これを試して見るべし。分からなければmyallocは気にしなくて良い。
#include <iostream>

struct myalloc_type{} myalloc;
void *operator new(size_t size, myalloc_type)
{
&nbap;&nbap;&nbap;&nbap;std::cout << "new\n";
&nbap;&nbap;&nbap;&nbap;return ::operator new(size);
}
void *operator new[](size_t size, myalloc_type)
{
&nbap;&nbap;&nbap;&nbap;std::cout << "new[]\n";
&nbap;&nbap;&nbap;&nbap;return ::operator new[](size);
}
int main()
{
&nbap;&nbap;&nbap;&nbap;char *buf = new(myalloc) char[100];
}
>>806
配列サイズが定数のときの挙動までは書いていない入門書もあると思われ。

808 名前:807 :03/10/11 14:24
ミスった。もう一回
#include <iostream>

struct myalloc_type{} myalloc;
void *operator new(size_t size, myalloc_type)
{
    std::cout << "new\n";
    return ::operator new(size);
}
void *operator new[](size_t size, myalloc_type)
{
    std::cout << "new[]\n";
    return ::operator new[](size);
}
int main()
{
    char *buf = new(myalloc) char[100];
}

809 名前:デフォルトの名無しさん :03/10/11 14:50
>>805
delete[]

810 名前:デフォルトの名無しさん :03/10/11 14:59
>>807
定数かどうかがどう関係あるんだろうか。

811 名前:デフォルトの名無しさん :03/10/11 15:00
実行時にバンドルなんたらって出るエラーは、
どういうとき出るエラーか、誰か教えてくだされ。


812 名前:デフォルトの名無しさん :03/10/11 15:52
newで配列を確保する場合、もしそれがクラスオブジェクトの配列ならば、
delete[]とdeleteのどちらでも、配列の要素すべてが解放される。
違いは、delete[]の場合全要素に対してデストラクタが呼ばれるのに対し、
deleteでは先頭要素のみデストラクタが呼ばれるということである。

と教科書に書いてあってびっくり。今まで知らなかった。

813 名前:デフォルトの名無しさん :03/10/11 16:02
まさか、未定義だろ
各処理系でどうかは知ったことでないが

814 名前:デフォルトの名無しさん :03/10/11 16:44
>>812
VC++だけ。

815 名前:デフォルトの名無しさん :03/10/11 18:06
>>312
そんな教科書捨てろ
どこに嘘が書いてあるかわかったもんじゃない

816 名前:デフォルトの名無しさん :03/10/11 23:48
C++の教科書は禿本かPrimerしかないと思ってるけど。
変に読者にこびったような本はダメぽ。


817 名前:デフォルトの名無しさん :03/10/12 00:15
禿本って何?禿く分かるC++?(謎

818 名前:B.S :03/10/12 00:30
禿々言うな。
お前等だって将来禿るかも知れないんだぞ?

819 名前:デフォルトの名無しさん :03/10/12 00:33
うるせー禿

820 名前:デフォルトの名無しさん :03/10/12 00:33
既につるっつるに剃りあげてますが何か?

821 名前:デフォルトの名無しさん :03/10/12 00:36
まだあるのに自ら剃るなんてなんて罰当たりな

822 名前:デフォルトの名無しさん :03/10/12 00:41
いやらしい程のM禿で、見るにみかねて、、、スレ違いスマソ

823 名前:デフォルトの名無しさん :03/10/12 05:27
>>816
確かにあの二冊は読者に優しくないよな。
分厚くて重くて大きくて・・・・

824 名前:デフォルトの名無しさん :03/10/12 05:37
>>823
私は禿本を風呂の中に持ち込んで読みましたが何か?
本は湯船につかってゆっくり読む習慣なので。

825 名前:デフォルトの名無しさん :03/10/12 05:48
>>824
ああなるほど。水に浮かべれば浮力で重さが気にならなくなると。

826 名前:デフォルトの名無しさん :03/10/12 06:23
>>823
私はあの本を見ながらオナニ○しましたがナニか?
「ハァハァ・・・・・vector
 ハァハァ・・・・・string
 ハァハァ・・・・・いてれーたぁー。」
と、このように。

827 名前:デフォルトの名無しさん :03/10/12 20:59
最近VC++触りだした、浦島太郎ですが。
VCでの最初のスタートは下記のようですが。
_tMain(....)
_tWinMain(....)

昔は  main()   WinMain()  だったはず。
どういった理由や意味で変わったのでしょう?
「_t」て、なに?
いろいろサーチしたけど、見つからなかったのでお願いします。


828 名前:デフォルトの名無しさん :03/10/12 21:11
>>827
UNICODEに対応させるため

829 名前:デフォルトの名無しさん :03/10/12 21:14
質問させて下さい。VC6.0です。

#include <iostream>
#include <iterator>
#include <sstream>
#include <conio.h>

void main()
{
std::wostringstream ss;
std::ostream_iterator<wchar_t, wchar_t> it(ss, L",");
*(it++) = L'A';
*(it++) = L'B';
*(it++) = L'C';
std::wcout << ss.str() << std::endl;
getch();
}

A,B,C, と表示されるのを期待してるんですけど、
wchar_tがshortとして扱われる為
65,66,67, と表示されてしまいます。
どうしたらいいんでしょう?


830 名前:デフォルトの名無しさん :03/10/12 21:19
>828 さんありがとうございます。
確かに昔は内部コードはSJISだったかな、(うろ覚え
「_t」でソース内の日本語文字列がUNICODEになって
オブジェクトになると考えていいですか?

831 名前:デフォルトの名無しさん :03/10/12 21:19
>>629
wchar_tを正しくサポートするコンパイラを使う。

832 名前:デフォルトの名無しさん :03/10/12 21:31
>>831
いい加減、VC++6ってのはもうダメだろ。金ないなら
.NETSDKにcl.exeついてくるんだからそれでもつかえと。
cygwinでもいいけどさ。

833 名前:829 :03/10/12 21:42
>>831-832
なるほど、VC6のせいでしたか。
boost::regex使ってて出た問題だったんですが、
これじゃ他の部分もまともに動いてるかどうか、わからないですね。
どうもありがとうございました。

834 名前:デフォルトの名無しさん :03/10/12 22:01
>>830自己レス。
main
_tmain     (Win32
_tWinMain   (MFC
でやってみたけど、EXEをHEXダンプで見たら、3つともSJISで
文字列入ってた、謎だ。
多分どこかが、UNICODEなんだろう、きっと・・・・・
何処なんだろうと、聞いてみる?^^;

835 名前:デフォルトの名無しさん :03/10/12 22:06
WinMain(HINSTANCE, HINSTANCE, char*, int);
wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int);


836 名前:デフォルトの名無しさん :03/10/12 22:17
>>834
828がUNICODEに対応させるとは書いたが、UNICODEになるとは誰も書いてない。

837 名前:デフォルトの名無しさん :03/10/12 22:50
コンパイルオプション

838 名前:デフォルトの名無しさん :03/10/12 23:01
>>833-837さんいろいろありがとう。
いろいろやって見て、一応の理解ができました。
ちなみに、>>829のソースはVC++.NET2003ではA,B,Cと出ます。
みなさんありがとーー

839 名前:デフォルトの名無しさん :03/10/13 00:07
>>834
そんなのどうでもいいから早くUnicodeでコンパイルする方法を調べろ

840 名前:デフォルトの名無しさん :03/10/13 01:42
>>829
std::locale::global(std::locale("japanese"));

841 名前:デフォルトの名無しさん :03/10/13 03:23
IDEとしてのVC6にはなんの不満もないので、cl.exeだけ差し替えて、
(バッチ使って別にコンパイルとかではなく)、そのまま使えないかなぁ…。

などと>>832見ながら思った秋の夜長…。

842 名前:デフォルトの名無しさん :03/10/13 03:35
>IDEとしてのVC6
class宣言がマクロ化されてるとアウトなのはちょっと勘弁してほしい
templateインスタンス型のメンバを保守できないとわかったときはズッコケた

843 名前:デフォルトの名無しさん :03/10/13 03:36
ncbdj状態も頻度高杉

844 名前:デフォルトの名無しさん :03/10/13 03:45
>>841
.NETSDKのcl.exeとPSDKとVC++6を組み合わせて使ってます。
特に問題ないです。

845 名前:デフォルトの名無しさん :03/10/13 04:01
.NET SDK の cl.exe は最適化できないとか言ううわさを聞いた気がするんだけど
その辺りどうなの?

846 名前:デフォルトの名無しさん :03/10/13 04:26
>>845
できないといわれてるけど、/G[3-7]オプションはとおるよ。
versionは13.10.3077

847 名前:デフォルトの名無しさん :03/10/13 09:31
/G[3-7]は単体で意味あんの?
/O[1-2]と組み合わせないと意味無いんじゃないの?

848 名前:デフォルトの名無しさん :03/10/13 10:06
>>847
Uni厨で済みませんでした。無知で恥かしいです。
$cl.exe /G6 /O2 test.c
Microsoft(R) 32-bit C/C++ Standard Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

cl : コマンド ライン warning D4029 : 標準の編集コンパイラでは最適化は使用できません。
test.c
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.

/out:test.exe

849 名前:デフォルトの名無しさん :03/10/13 10:12
つーかgccでも単体で-march=i686なんてやらないで-O2とか-O3と組み合わせて使うよね。

850 名前:デフォルトの名無しさん :03/10/13 11:45
RDBで複数の項目にインデックスを貼って高速に検索できるのと同じように、
2種類以上の項目で対数時間で検索ができるようなコンテナはC++には無いですか?
分かりやすく言うと
class Board
{
 std::string name_;
 int id_;
 time_t time;   

 //メソッド省略
 //findByName(), findById(), findByTime() 
};

このようなクラスのインスタンスをたくさんコンテナに格納して、
findByName(), findById(), findByTime()のどれでも線形時間ではなく、
対数時間で結果のイテレータが帰ってくるようなコンテナが欲しいんですが。

851 名前:デフォルトの名無しさん :03/10/13 12:28
>>850
標準だと無いと思うよ。

852 名前:デフォルトの名無しさん :03/10/13 15:10
後学のために伺いたいのですが、
「std::listの要素をサーチして、条件が一致したものをlistからeraseしていく」

…という作業を、普通に初期化した形のfor文で、
実現することは出来ないのでしょうか?

853 名前:デフォルトの名無しさん :03/10/13 15:23
>>852
なぜforで? std::remove_ifじゃ駄目?

まあ、forで手書きするならこんな感じか:
typedef list<T> some_list_t;
some_list_t a_list;
for ( some_list_t::iterator p = a_list.begin(); p != a_list.end(); ) {
 if ( 条件 ) {
  p = a_list.erase(p);
 } else {
  ++p;
 }
}


854 名前:デフォルトの名無しさん :03/10/13 15:44
下記のコードでなぜか最後の行が2回読み込まれてしまうようで、
最後の人が2人になってしまいます。
どう書き直せばいいのでしょうか?

ifstream ifs("address.txt");
vector<Person*> vec;
string name, address;

while(ifs)
{
 ifs >> name >> address;
 vec.push_back(new Person(name, address));
}

855 名前:852 :03/10/13 15:44
>>853
レスサンクスです。いえ、なんの変哲もない順次サーチ=for文、
みたいな固定観念ができてしまっていて…。

for文の例、およびremove_ifの提示ありがとうございました。
remove_if使ったこと無かったです。これから調べてみます。便利ですね。

856 名前:デフォルトの名無しさん :03/10/13 15:47
>>855
あ、listには専用にメンバ関数としてremove_ifがあるから
それ使うよろし

857 名前:デフォルトの名無しさん :03/10/13 15:54
>>856
了解しました。追い銭重ね重ね感謝。

858 名前:854 :03/10/13 15:56
自己解決しました。
こうやったらうまくいきました。

for(;;)
{
ifs >> id >> name;
 if(!ifs)
  break;
 boards_.push_back(BoardPtr(new Board(id, name)));
}

859 名前:854 :03/10/13 15:57
間違えて元のコードを晒してしまいました…

860 名前:デフォルトの名無しさん :03/10/13 17:11
>>850
std::set<boost::shared_ptr<Board> > index_by_name(pred(BY_NAME));
みたいなのをインデックスにしたい項目の数だけ作って全部に登録、とか?

861 名前:デフォルトの名無しさん :03/10/15 01:38
下記のコードですが、count_ifのところでsegfaultを起こしてしまいます。
どこがおかしいんでしょう?

#include <iostream>
#include <vector>
#include <algorithm>


static bool check_c(char input){
return input=='c';
}

int main(){
vector<char> sequence;
int c;
for(int i =0; i < 2; i++)
for(int j =0; j < 5; j++)
sequence.push_back( 'a' + j );
cout<<sequence.begin()<<endl;
cout<<endl;

c = count_if<vector<char>::iterator, bool(char)>(sequence.begin(), sequence.end(), check_c);
c = count<vector<char>::iterator, char>(sequence.begin(), sequence.end(), 'c');

cout<<c<<endl;
}


862 名前:デフォルトの名無しさん :03/10/15 01:48
>>861
segfault以前にコンパイル通らないはずだから確かめてないけど。

> cout<<sequence.begin()<<endl;
ここだろうね。

863 名前:デフォルトの名無しさん :03/10/15 01:53
不完全クラスに継承関係を明示する方法ってあります?

基底クラスのポインタに変換するのに、無理矢理reinterpret_castして、
とりあえず正常に動かすことは出来るのですが。

864 名前:861 :03/10/15 01:56
>>862
その行をコメントアウトしても変化はありません。

実は、そこはただの手抜きで…
デバッガから見て、char* だったのでつけ足しただけのものなんです。

865 名前:デフォルトの名無しさん :03/10/15 02:00
c = count_if<vector<char>::iterator, bool(char)>(sequence.begin(), sequence.end(), check_c);



c = count_if( sequence.begin(), sequence.end(), check_c);

にしてみる。

866 名前:デフォルトの名無しさん :03/10/15 02:03
>>864
count_ifの中は追ってみたの?
なんにせよコンパイラもSTLの種類も示されないんじゃなんともね。
using namespace std;が抜けてるみたいだし。

867 名前:デフォルトの名無しさん :03/10/15 02:04
>>861
count_if<vector<char>::iterator, bool(*)(char)>

bool(char)でコンパイル通るのが悪いと思うんだが。

868 名前:デフォルトの名無しさん :03/10/15 02:06
>>867
bool(char)は正しい表記だったと思うよ

869 名前:デフォルトの名無しさん :03/10/15 02:07
>>868
表記は正しいが、そのテンプレート引数だと関数型を値渡しすることになる。
関数型の値渡しができたっけ?

870 名前:デフォルトの名無しさん :03/10/15 02:11
>>869
bool(char)はbool(*)(char)と同等だった気がする。
どこで見たのかは忘れたが。

871 名前:870 :03/10/15 02:20
>>869
ゴメン、激しく俺の勘違い

872 名前:デフォルトの名無しさん :03/10/15 02:37
>>867
それが正解でした。ありがとうございます。
コンパイラは、gcc-2.96-113 というRedhat Linuxのものです。

本来は通らないはずのコードだったのか…

873 名前:デフォルトの名無しさん :03/10/15 02:38
gcc 3.3.1 (cygming) でテストしてみた。

↓は"redefinition of `int call(int (*)(int))'"
int call( int x(int) ){ return x(0); }
int call( int(*x)(int) ){ return x(0); }

↓はエラー無し
template< typename Function >
int call( Function x ){ return x(0); }
template int call<int(int)>( int(int) );
template int call<int(*)(int)>( int(*)(int) );

バグってるように見える。
>>861はgccかな?

874 名前:デフォルトの名無しさん :03/10/15 02:43
VC++7.1

template< typename T > char const* typename_of( T r ){ return typeid( r ).name(); }
int main(){
std::cout << typename_of< bool(char) >( check_c ) << std::endl;
std::cout << typename_of< bool(*)(char) >( check_c ) << std::endl;
}

一つ目は関数が値渡しされてた。
式内ではどちらも関数ポインタとして扱われるもよう。

875 名前:デフォルトの名無しさん :03/10/15 02:56
8.3.5 -3- より。
"After determining the type of each parameter, any parameter of type ``array of T'' or ``function returning T'' is adjusted to be ``pointer to T'' or ``pointer to function returning T,'' respectively."

というわけで、関数の引数においては>>870が正しいみたい。

14.8.2 -3- によると、
この変換がテンプレートのときにもいちおう関係はするようだが、
Noteとして書かれている
"f<int>(1) and f<const int>(1) call distinct functions even though both of the functions called have the same function type."
というのが怪しい。
変換後の仮引数がいっしょになるとしても、別々の関数としてコンパイルされるみたい。

で、gccで試したところでは、bool(*)(char)で実体化したほうは正しく動作するが、
bool(char)で実体化したほうのコードが死んでるっぽい。
仮引数リストは同じなので同じコードになるはずなのに、
bool(char)で実体化したときになんだかへんなコードが出る。クラッシュするコードかどうかは未確認。

876 名前:861 :03/10/15 03:29
バグ持ち(bool(char))とバグ無し(bool(*)(char))のアセンブラ出力をdiffで並べてみました。
スタックに積んでルーチン呼ぶまでは一緒ですが、確かにルーチン内の処理が各々で異なっています。

--- bug.s Wed Oct 15 03:14:53 2003
+++ non-bug.s Wed Oct 15 03:13:55 2003
@@ -17,25 +17,21 @@
movl %eax, %eax
pushl %eax
.LCFI10:
- call count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
+ call count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
------------------------------------------(略)----------------------------------------------------
- .section .gnu.linkonce.t.count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,"ax",@progbits
+ .section .gnu.linkonce.t.count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,"ax",@progbits
.align 4
- .weak count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
- .type count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,@function
-count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type:
+ .weak count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
+ .type count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,@function
+count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type:



877 名前:861 :03/10/15 03:30
.LFB10:
pushl %ebp
.LCFI38:
movl %esp, %ebp
.LCFI39:
- subl $24, %esp
+ subl $8, %esp
.LCFI40:
- movl 16(%ebp), %eax
- movl 20(%ebp), %edx
- movl %eax, -8(%ebp)
- movl %edx, -4(%ebp)
- movl $0, -12(%ebp)
+ movl $0, -4(%ebp)
.p2align 2
.L54:
movl 8(%ebp), %eax
@@ -45,28 +41,28 @@
.p2align 2
.L57:
subl $12, %esp
- leal -8(%ebp), %edx
movl 8(%ebp), %eax
movsbl (%eax),%eax
pushl %eax
+ movl 16(%ebp), %eax
.LCFI41:
- call *%edx
+ call *%eax

878 名前:デフォルトの名無しさん :03/10/15 04:38
x86のアーキテクチャ調べて来たよん。
結局、lealで関数ポインタを二重参照しているのが原因とわかりました。

count_if(8(%ebp),12(%ebp),16(%ebp)){
movl 16(%ebp), %eax
movl %eax, -8(%ebp)
leal -8(%ebp), %edx
call %edx
}
↓省略
count_if(8(%ebp),12(%ebp),16(%ebp)){
leal 16(%ebp), %edx
call *%edx
}
↓C++風に。
count_if(*a,*b, void (*func)()){
*(&func)();
}

879 名前:863 :03/10/15 05:05
こっちも意見を聞かせてよ。
ソースがないから駄目なのか?

<B.H>
class B {};
<D.H>
#include "B.H"
class D : public B {};

<sub.cpp>
#include "D.H"
D dins;
D *d = &dins;

<main.cpp>
#include "B.H"
class D;
void func(B *b) {}
void main(void)
{
extern D *d;
func(d);
}

func(d)をfunc(reinterpret_cast<B *>(d))にすれば、
とりあえずちゃんと動くけど
そもそも不完全クラスの宣言に
class D : public B;
と言う意味を持たせて、reinterpret_castを使わずに済ます方法はないでしょうか?

880 名前:デフォルトの名無しさん :03/10/15 05:29
>>879
D も B もわかって無いのに reinterpret_cast 以外のキャストをどうやって実行するの?
君の使ってるコンパイラが
static_cast< B* >( D* ) == reinterpret_cast< B* >( D* )
だとしても、他の環境でもそうとは限らない。

class D: public A, public B;
なら、多分君のコンパイラでも static_cast< B* >( D* ) するためには sizeof( A ) がわからないといけないはず。

881 名前:デフォルトの名無しさん :03/10/15 05:58
>>879
D * dではなくて B * dでいいと思うけど。
そうすればmainからDについて知る必要ないし。
//base.h
class Base{public:
    virtual void print()=0;
    virtual ~Base(){}};
//Test.h
class Test:public Base{public:
    void print();}:
//func.h
Base * CreateTest();
//sub.cpp
#include "Base.h"
#include "Test.h"
#include "func.h"
#include <iostream>
Base * CreateTest(){
    return new Test;}
void Test::print(){
    std::cout << "Test::print()" << std::endl;
}
//main.cpp
#include "Base.h"
#include "func.h"
int main(){    Base * p=CreateTest();
    p->print();//Test::printが呼ばれる
    delete p;
    return 0;
}
まあ実際はboost::shared_ptrとかstd::auto_ptrとか使うだろうけど。

882 名前:デフォルトの名無しさん :03/10/15 06:51
>881
ああそうか、自分の例で言うところの
extern D *d;
が、そもそもD *でなくてもB *で充分ですね。

何でこんな単純なことに気が付けなかったんだ?
とにかくこれで安心して眠れます。ありがとうございました。

883 名前:デフォルトの名無しさん :03/10/16 23:23
つかぬ事をお伺いしますが、ローカルにおける文字列リテラルが
static constであることは言語規格上、保証されていますでしょうか?


884 名前:デフォルトの名無しさん :03/10/16 23:28
>>883
ISO/IEC14882:1998(E)の規格票は買ったか?
ここは使ってみたか?

http://www.excite.co.jp/world/text/

まさか禿本持ってなかったりしないだろうな?

885 名前:B.S :03/10/17 01:23
禿々言うな。
お前等だって将来禿るかも知れないんだぞ?

886 名前:デフォルトの名無しさん :03/10/17 12:30
C++のコードをJavaに書き直すことはできますか?

887 名前:デフォルトの名無しさん :03/10/17 13:34
>>886
質問の意味がうまく絞れないんだが。

888 名前:886 :03/10/17 13:39
1394カメラをJavaで動かしたいんですけど、
Javaでの動かし方がよくわかりません。
そのカメラには、付属のアプリケーションが付いており、
そのソースコードも付いてました。(VCとC++)
なので、そのコードをJavaに書き直してもらいたいのです。


889 名前:883 :03/10/17 13:48
すまん、禿...もといStroustrup本に書いてあった。
「文字列リテラルの型はconst char[N]であり...
静的に割り当てられる。」
char*への代入が許されるから、定数として扱うかはベンダ依存かと思ってた。

ISO/IEC14882:1998(E)の規格票は持っていない。
つか欲しいんだけどどこで手に入る?


890 名前:デフォルトの名無しさん :03/10/17 15:01
JavaってIEEE1394というデバイスを叩けたっけ?

891 名前:デフォルトの名無しさん :03/10/17 15:53
>>890
叩けるよ!

892 名前:デフォルトの名無しさん :03/10/17 17:21
>>888
Linux とかならできるんじゃない?

Windows だと、そのへんは stream class mini driver をDirectShow の API が
ラッパするような形になってると思うんだけど、これは Java からは使えません。

893 名前:デフォルトの名無しさん :03/10/17 18:41
>>889
> ISO/IEC14882:1998(E)の規格票は持っていない。
> つか欲しいんだけどどこで手に入る?
http://www.techstreet.com/cgi-bin/detail?product_id=49964 とかで買える。

もっと新しい ISO/IEC 14882:2003 もすでにpublishは
されてるはずなんだけど、どうやったら手に入るのかわからん。。。

894 名前:デフォルトの名無しさん :03/10/17 20:12
複数種類のクラスをしまっておけるバッファを作る時、

class A;
class B;

class Buf {
union {
A a;
B b;
};
}

コンストラクタのあるクラスだとunionは使えないんですが、何かいい手はないでしょうか?
マクロかboostか何かでmax(sizeof(A), sizeof(B))を取ってやるしかないんでしょうか。


895 名前:デフォルトの名無しさん :03/10/17 20:29
>>894
cvsからboostの最新版を落としてきてboost::variant。これ。

896 名前:デフォルトの名無しさん :03/10/17 20:47
>>895
あれは使っているコンパイラでエラーが出ます。


897 名前:デフォルトの名無しさん :03/10/17 21:02
>>893
ttp://jbbs.shitaraba.com/bbs/read.cgi/computer/5651/1048584888/123-

898 名前:ファイル :03/10/17 21:18
読み込みたいテキストファイルの前半にに不必要な部分があるのですが、
その部分を除いてそのテキストファイルを読み込むことはできますか?
c言語初心者です、お願いします。

899 名前:デフォルトの名無しさん :03/10/17 21:28
【1:898】「C++」相談室 part23

900 名前:デフォルトの名無しさん :03/10/17 21:39
むむ、オヌシ初心者だな。

901 名前:デフォルトの名無しさん :03/10/17 22:14
>>889
C++に限らず
ここは知っておくべきでしょう

http://www.jsa.or.jp/

902 名前:デフォルトの名無しさん :03/10/17 22:42
>>898
できます。

903 名前:ファイル :03/10/17 23:08
c言語の本をまだ一冊しか読んでないので、
よくわからないのですが、どうしたら不必要な部分を
除いて読み込むことができるのですか?教えてください。

904 名前:デフォルトの名無しさん :03/10/17 23:11
>>903
ここはC言語のスレではありません

905 名前:デフォルトの名無しさん :03/10/17 23:17
>>903
Cスレこっち

http://pc2.2ch.net/test/read.cgi/tech/1064234533/l50

906 名前:デフォルトの名無しさん :03/10/18 00:01
>>894
何でそんなことしたいのかが分からん。
自分で取ったバッファ内に A とか B のインスタンスを作りたいんだったら、
placement new 使え。


907 名前:894 :03/10/18 01:03
>>895
なるほど、そんなもんがあるんですか…
しかしcvsから取ってくるのはちょっと恐いなぁ。せめてリリースされてるのに入ってればいいんだけど…

>>906
通信回りのバッファの扱いとか、パフォーマンスを気にする時のメモリ管理とか、
結構色々使います。
要するにunionが使いたいところです。


908 名前:デフォルトの名無しさん :03/10/18 01:09
>>907
ならやっぱりplacement newでいいんでは?

909 名前:894 :03/10/18 01:20
>>908
いや、placement newする前、どれくらいの大きさのバッファを確保するか、の方にからむ問題です。


910 名前:デフォルトの名無しさん :03/10/18 01:44
>>909
template<int a, int b>
class Max
{
enum{Value = a > b ? a : b};
}

char buf[Max<sizeof(A), sizeof(B)>];


911 名前:デフォルトの名無しさん :03/10/18 01:59
あっ、適当に書いたから間違いまくってるや・・・

template<int a, int b>
class Max
{
public:
enum{Value = a > b ? a : b};
}

char buf[Max<sizeof(A), sizeof(B)>::Value];


912 名前:894 :03/10/18 02:03
>>910
そうですね、そんな感じでやるかなぁというのを894の最後に書いてみたんですが、
これだとちょっと嫌な点があって、アライメントで問題が起きる可能性があるんですよね。
まぁそれは、気にしながらclass Bufの中身の配置をするか、
複数クラスの入る場所の大きさにゆとりを持たせて先頭をちょっと調整するかだと思うんですが、
union的に扱えればずっと楽なのでそういうのないかなぁと。

あと、微妙に直観的じゃないのが嫌とか、実際には数10個のクラスを押し込むので
タイプリストを作って全体のMaxを取らなくちゃとか、微妙に腰が引ける感じが…
もちろんこちらは本質的な問題ではないんですけどね。


913 名前:デフォルトの名無しさん :03/10/18 02:22
>>894
class A{};
class B{};

class Buf {
    char buf[sizeof(A)>sizeof(B)?sizeof(A):sizeof(B)];
public:
    A & GetA(){return *reinterpret_cast<A*>(buf);}
    A & GetB(){return *reinterpret_cast<B*>(buf);}
    template <typename T> T & Get{return *reinterpret_cast<T*>(buf);}
};

int main(){
    Buf o;
    new (&o.GetA()) A;
    o.GetA().~A();
    return 0;
}
//やや力押し気味、lokiのタイプリストとか使えば3つ以上のunionにも使えるだろうけど


914 名前:デフォルトの名無しさん :03/10/18 02:31
classをバイナリコピーするの?

915 名前:デフォルトの名無しさん :03/10/18 02:34
union で持たせるメリットが分からないなぁ。メモリ節約したいって話なら、
operator new を自前で書いて、使う側は void* ででも受けとけば良いん
じゃないの?

916 名前:デフォルトの名無しさん :03/10/18 03:24
>union で持たせるメリット

だから、アライメントだろ?


917 名前:894 :03/10/18 03:49
>>915
うーん、節約したいというわけではないけど。例えば…

class UserBase {
int user_defined_info;
};

class A : public UserBase {}; // class Bも同様

class Elm {
Elm *next;
union {
A a;
B b;
};
};

Elmは自分が使う側、ユーザはAだのBだのを使う感じで、
Elmのリストの中からuser_defined_infoを拾ってくる場合とか。
Elmの中にUserBase *を埋めておくだけという実装も可能だけど、それだと遅くなるとか、
Elmのサイズが揃ってるとメモリ管理が容易になるとか、
ライトバリアのかかったページにしかオブジェクトをおいちゃダメとか(これは今思いついただけだけど)、
まぁそれなりに状況は考えられますね。


918 名前:デフォルトの名無しさん :03/10/18 03:58
そこまでかつかつに効率を求めるならクラス化する必要は無いと思うが。

919 名前:894 :03/10/18 04:23
>>918
そいつはそうなんですけどね。

でもまぁ少しでも楽ができてかつバグの入りにくい形にしたいじゃないですか。
今のところ、単なるstructで逃げたり、char[MAX_SIZE]で逃げたり、
Base *で逃げたりしてるわけですけど、もう少し何とかならんかなぁと。

紹介してもらったboost::variantが早く標準にならないかなぁ。
variantはコンストラクタ・デストラクタはどういう扱いなのかな?
調べておくか…


920 名前:デフォルトの名無しさん :03/10/18 04:26
class A{
std::vector<std::vector<double> > a;
public:
A(std::vector<std::vector<double> > b =
std::vector<std::vector<double> >()) : a(b) {}
};

という感じのクラスがあります。他にも関数がありますが、std::deque
でも出来る操作しか使っていません。このクラスのコンテナを
vectorとdequeから選んだり、コンテナの中の型をdouble以外の
ものにしたりするためにテンプレートを使いたいのですが、
やり方が分かりません。どうか教えてくださいませ。。

921 名前:デフォルトの名無しさん :03/10/18 04:26
>>918
ゲームでも作るんですか?
何かそれっぽい気がしたんですけど。

922 名前:デフォルトの名無しさん :03/10/18 04:34
template<class T, typname U>
class A{
T< T< U > > a;
とかか?

923 名前:デフォルトの名無しさん :03/10/18 04:39
>>920
その程度ならtypedefしとくだけで1行書き換えれば変更できるようになる。

924 名前:デフォルトの名無しさん :03/10/18 04:43
template<template<typename> class Container, typename T>
class A{
Container<Container<T> > a;
public:
A(Container<Container<T> > b =
Container<Container<T> >()) : a(b) {}
};

A<std::vector, double> hoge; // のように使う

でも>>923が正解な気がする。

925 名前:デフォルトの名無しさん :03/10/18 05:01
>>922-924 有難うございます。
typedef std::vector Container;
typedef std::deque Container;
のどちらかを条件コンパイルするかコメントアウトするかして
クラス定義内でContainerを使うということですね。
ちなみに、Containerにstd::listを使いたいときは、>>924さんの
方法に部分特殊化を使えばいいのでしょうか?

926 名前:デフォルトの名無しさん :03/10/18 14:28
>>917
> Elmの中にUserBase *を埋めておくだけという実装も可能だけど、それだと遅くなるとか、
本当に遅くなるか吟味した方が良いぞ。

特にキャッシュが少ない環境だと、大きなデータをリストでつなぐより、小さなインデクスを
配列にとってデータは void* の先においておく方がキャッシュミスが減ったりするし。

927 名前:デフォルトの名無しさん :03/10/18 14:33
>>918
クラス化するなというか、コンストラクタ・デストラクタを自前で定義しなければ良いだけ
だよね。初期化用のメンバ関数を別に定義すれば良いだけ。

そういう形で使う以上、いずれにせよ A, B の確保・解放はユーザ側ではなく Elm 側で
行うんだろうし。

928 名前:デフォルトの名無しさん :03/10/18 17:43
鈴木宗男氏が立候補を断念したそうだ。

929 名前:デフォルトの名無しさん :03/10/18 17:48
>>928
誤爆orスレ違いだ。そう言う話題は↓でしろよ。
http://pc2.2ch.net/test/read.cgi/tech/1036811974/l50

930 名前:デフォルトの名無しさん :03/10/18 18:14
Visual C++ Runtime Library の メッセージボックスが開いて、
Runtime Error!
とメッセージを残して、強制終了(ノToT)ノ  なぜだ〜

931 名前:894 :03/10/18 19:00
>>921
サーバとか、言語処理系とか、ゲームとか。

>>926
そうですね。まぁ>>917の例でAがでかくなったらUserBaseのみElmに入れて
A固有メンバはpimpleでしょうけど。
まプロファイル取らないとなんとも。

>>927
そうですね。その方法でいいと思いますが、
微妙に嫌なのは、デフォルトコンストラクタに相当するものが
void A::init() { UserBase::init(); ... }
と、必ずBaseクラスの初期化メソッドを明示的に呼ばなきゃいけない点かな。


932 名前:ちんげ :03/10/18 19:04
c++のソフトはwinnyで落とそう。

933 名前:デフォルトの名無しさん :03/10/18 21:28
クラスのメンバ関数で
引数に継承元のクラスのオブジェクトを入れたら
「シンタックスエラーerror C2061: 構文エラー : 識別子 'class1' がシンタックスエラーを起こしました。」
というエラーが出てしまいます。
何が原因なんでしょう?
後、シンタックスエラーって何ですか?


934 名前:デフォルトの名無しさん :03/10/18 21:38
>>933
文法違反。

935 名前:デフォルトの名無しさん :03/10/18 21:41
シンタックス=文法論
セマンティクス=意味論
つーか、ぐぐれよそんくらい

936 名前:デフォルトの名無しさん :03/10/18 21:44
【演習】次の例文に含まれる、シンタックスエラーとセマンティクスエラーをなるべく多く指摘せよ。
C++のソフトを
そんな悪いインターネットから落としたら
危険が危ないよ



937 名前:デフォルトの名無しさん :03/10/18 22:23
>>931
なぜ placement new を嫌がるのかさっぱりわからん。

class C
{
public:
C( bool is_A ) : is_A( is_A ){ is_A ? (void)new(buf)A : (void)new(buf)B; }
~C(void){ isA() ? (void)asA().~A(): (void)asB().~B(); }
A& asA(){ return *reinterpret_cast< A* >( buf ); }
B& asB(){ return *reinterpret_cast< B* >( buf ); }
A const& asA() const{ return *reinterpret_cast< A const* >( buf ); }
B const& asB() const{ return *reinterpret_cast< B const* >( buf ); }
bool isA() const{ return is_A; }
private:
bool is_A;
char buf[sizeof( A )>sizeof( B ) ? sizeof( A ) : sizeof( B )];
};

asA() 等の呼び出しは最適化で消えてなくなり、直接アクセスしたのと同じことになる(VC7.1で確認)。
無理やり union 使ってキモイ思いするよりはるかに良い。

938 名前:デフォルトの名無しさん :03/10/18 22:29
つか、unionって使ったことない。
そんなにメモリの節約がしたいのか?

939 名前:デフォルトの名無しさん :03/10/18 22:51
http://www.cs.wisc.edu/~ghost/gsview/get45.htm
のコンパイルがうまくいきません。
readme.htmの指示どおりに調節したのですが、

"C:\Program Files\Microsoft Visual Studio\common\msdev98\bin\rc" -D_MSC_VER -D_Windows -D__WIN32__ -I"C:\Program Files\Microsoft Visual Studio\vc98\include" -i"C:\Program Files\Microsoft Visual Studio\vc98\include" -i".\src" -i".\srcwin" -i".\obj"
-i"en" -fo.\obj\gsvw32en.res .\srcwin\gvwin1.rc
指定されたパスが見つかりません。

というエラーが出ます。これはどうすればよいでしょうか?

940 名前:デフォルトの名無しさん :03/10/18 22:53
>>939
指定したパスがあるかどうか確認したら?

941 名前:894 :03/10/18 22:53
>>937-938
いやだからplacement newは当然使えるし、必要なら使うんですよ。unionであっても。
問題はそこじゃないんですよ。

937の例でいうなら、もしAとかBにアライメントが必要な要素が入ってたらダメでしょ?
別にメモリの節約のために使ってるんじゃないんですよ。


942 名前:デフォルトの名無しさん :03/10/18 22:55
>>941
何が問題になるの?

943 名前:デフォルトの名無しさん :03/10/18 22:57
>>937-938
union知らないなら黙ってた方が良いよ


944 名前:デフォルトの名無しさん :03/10/18 22:58
>>942
アライメントの問題だと何回書かれたら分かるんだ?

945 名前:デフォルトの名無しさん :03/10/18 22:59
>>944
それが、わからないから聞いてるんだ。
具体的にA、Bがどういう型のとき問題になるのか教えてちょ。

946 名前:デフォルトの名無しさん :03/10/18 23:02
>>945
ちょっとアライメントを勉強したほうがいい

仮想関数もってるだけでダメになる場合もあるぞ

947 名前:デフォルトの名無しさん :03/10/18 23:09
sizeof(A) って、アライメントとか仮想関数テーブルへのポインタ込みのサイズ返すんじゃないの?


948 名前:デフォルトの名無しさん :03/10/18 23:14
>>947
そうだよ

949 名前:デフォルトの名無しさん :03/10/18 23:21
>>948
じゃあ、何が問題なん?
普通に sizeof(A) 分のバッファ確保しとけば union なんて無くても placement new 出来るじゃん。


950 名前:デフォルトの名無しさん :03/10/18 23:25
そのバッファのアライメントがAのアライメント要求を満たさなければならない。

951 名前:デフォルトの名無しさん :03/10/18 23:27
>>950
それはコンパイラの制限でしょ?

952 名前:894 :03/10/18 23:32
>>949
937の例でいうと、char buf[]の先頭がアライメントを意識して置かれていない可能性があるのが問題です。


953 名前:デフォルトの名無しさん :03/10/18 23:39
>>952
static void* operator new(size_t) を適切に定義しておけ。

954 名前:デフォルトの名無しさん :03/10/18 23:41
>>953
もうオマエは黙ってろよと、見当違いもいい加減にシロ

と894は思ってるよ、多分

955 名前:デフォルトの名無しさん :03/10/18 23:42
>>951
意味がわかりません。
仮に、「それ」が「コンパイラの制限」だとしたら、
「普通に sizeof(A) 分のバッファ確保しとけば placement new 出来る」ことになるのですか?

956 名前:894 :03/10/18 23:48
>>953
それで逃げる手が一つですね。ただしその場合は、Elm側からAにアクセスするたびに
必ずアライメント計算をしなくちゃならなくなります。

あ、もちろんbufのサイズは max(sizeof(A), sizeof(B))+アライメント分
にしておかないとダメです。

とりあえず
struct X {
char a;
char buf[8];
};
struct Y {
char a;
union {
char buf[8];
double d;
};
};
のsizeofでも見て、Y.dにアクセスしたい時の事を考えてみて下さい。

957 名前:デフォルトの名無しさん :03/10/18 23:48
>>941
A とか B の placement new を、アライメント意識して書けば良いだけだと思うが……。
デフォルトだと「渡されたアドレスそのまま」返すことになってるけど、別にオフセット
調整しても良いんだし。

いちいちクラス毎に placement new 実装するのがダサイって話だと、そもそも
アライメント調整必須な段階で placement じゃない new も書き直す必要がある
(全部の処理系とはいわないが gcc 3.x とかはそう) から、手間は変わらないよ。
自動変数や static 変数だと、コンパイラ・リンカがよろしく取りはからってくれるけど、
new 使うとなると自前で工夫するのは大前提。

958 名前:デフォルトの名無しさん :03/10/18 23:48
じゃあ、bufの前にintでもおいて、alignmentを意図すればいいじゃないか。
あるいは、charでなく、intでbufを確保する手もあるし。

959 名前:デフォルトの名無しさん :03/10/18 23:51
え?なんでstatic void* operator new(size_t) を適切に定義することが回避方法になんの?

char buf[5454];
new(buf) A;

としてもその再定義したnewは呼ばれないぞ?

960 名前:デフォルトの名無しさん :03/10/18 23:52
>>959
たぶん引数に void* を書き忘れてるんだと思うが。

961 名前:デフォルトの名無しさん :03/10/18 23:53
>>958
世の中には8バイトアライメントや16バイトアライメントを必要とするものがあるのだよ

962 名前:デフォルトの名無しさん :03/10/18 23:54
>>961
なら char を 7 つとか 15 とか挟んどけ。

963 名前:894 :03/10/18 23:56
>>957
see 956
>>958, 962
see 912

>>959
その通りでした。文脈で明らかにplacement newの話だと思ったので
そう思い込んで返事しました。

964 名前:デフォルトの名無しさん :03/10/18 23:56
>>962
アフォですか?

965 名前:デフォルトの名無しさん :03/10/19 00:00
>union的に扱えればずっと楽なのでそういうのないかなぁと。

結局、「ない」ってのが答えだろ。

966 名前:デフォルトの名無しさん :03/10/19 00:13
>>895-965 みたいなのを全て考えた上で boost::variant が
あるんだから、素直に使うかせめてソース読むかしようよ…
と思うんだがどうか。 1.31に入ることは確定してるから待つんでもいいが。 >>907

967 名前:デフォルトの名無しさん :03/10/19 00:13
>>963
そもそも 894 の段階で、A, B が特定のアライメントを要求するなら、暗黙の Buf::new(size_t) を
使って new Buf できなくなってるワケだが……。

968 名前:894 :03/10/19 00:23
>>966
おっしゃる通りです。私も別にboost::variantを使わないつもりはないのでそうします。
boostがどうやって回避してるか非常に興味深いし。

途中で「どうしてplacement newじゃダメなの?」とか言われたから
「まぁそういう疑問を持つ人も居るのかな?」とか思って返事したまでで。
特にゴネてるつもりはなかったんですが…

>>967
これ本当?unionなら大丈夫でしょ?そう信じて今まで書いてきたんだけど…


969 名前:937 :03/10/19 00:30
お前らが騒いでる間に任意のアラインメントに対応できるコード書いた。
長いのでどっか貼り付けてくるからまってれ。

970 名前:デフォルトの名無しさん :03/10/19 00:31
>>968
> これ本当?unionなら大丈夫でしょ?
処理系・ライブラリ依存だと思うが、俺の環境 (gcc 3.2 にベンダーがローカルな
パッチを当てたもの) だとダメだった。new Buf すると、単に

void *p = ::operator new(sizeof(Buf))

でヒープからメモリを持ってきて、この p をオフセット調整なしで使う。

だから 32byte aligned なメモリが欲しければ Buf クラスの operator new を自前で
定義して 32byte aligned なメモリを持ってくるように書き直す必要がある。

自動変数ならばコンパイラがスタックフレームポインタ調整を入れるし、static, global
変数はリンク時にリンカがメモリを適切に割り当てるから問題ないんだけど。

971 名前:デフォルトの名無しさん :03/10/19 00:38
>>970
それは単に class A と class B にアラインメントが必要ないからではなかろうか。

972 名前:デフォルトの名無しさん :03/10/19 00:48
>>971
そんなことはない。ちょうど先日はまった話なんだが

class Foo {
  u_char buf[1024] __attribute__((aligned(64))); // このメンバ変数は 64 バイトアライメント
};

といったクラスを用意して new Foo したら、buf か必ずしも 64 バイトアライメントされずに
困った。

アセンブラコードを出力させて調べたら >>970 みたいな状況だったので、Foo クラス内に

static void* operator new(size_t n) { return memalign(64, n); }
// memalign は指定したアライメントでヒープからメモリを切り出す関数

と追加して事なきを得た次第。

973 名前:937 :03/10/19 00:55
http://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/readres.cgi?bo=lounge&vi=999294620&res=107

仮想関数の無いクラスのアラインメントは最初のプリミティブのアラインメントと等しいという仮定を置いてます。

974 名前:デフォルトの名無しさん :03/10/19 01:00
>>972
PS2でつか?

struct aligned_t{};
namespace{ aligned_t aligned; }
void *operator new(size_t size,aligned_t,size_t n) {
return memalign(n,size);
}

int main(){
int *p=new(aligned,64) int;
}

こういう解決方法はどう?

975 名前:デフォルトの名無しさん :03/10/19 01:10
>>974
> int *p=new(aligned,64) int;
それも良いアイデアだと思うけど、うっかり new(aligned, 64) Buf すべきところを new Buf しても
コンパイル時に検出できないのが悲しい。

C++ だと、ランタイムエラーよりはコンパイルエラーの方が何かと幸せだから。

976 名前:デフォルトの名無しさん :03/10/19 03:11
CISCの派生CPUしか使った事がない
人ばかり見たいですね。このスレは。
でもその派生CPUでも高速化のためには
必要なんですけどね。
アライメント調整。


977 名前:デフォルトの名無しさん :03/10/19 04:03
普通に struct A, struct B と

const int MAX_SIZE = Max<sizeof(A), sizeof(B)>::Value;
struct Buffer
{
enum{BUFFER_SIZE = MAX_SIZE / sizeof(int) + 1};
int buf[BUFFER_SIZE];
}

とか定義しといたら、A も B も Buffer もその先頭が
アライメント境界にくるように自動的に調整されないの?

調整されるんだったら、Buffer 型の配列作っといて、
それのアドレスを placement new に渡せば問題ないんじゃないの?


978 名前:デフォルトの名無しさん :03/10/19 04:09
>>975
mallocで確保したメモリがどんなアライメント要求も満たすのが前提だから、
dlmallocにアライメント設定してmalloc置き換えるようにリンクさせればいいんじゃない?

979 名前:デフォルトの名無しさん :03/10/19 04:19
>>977
Buffer はアラインメント境界に来るけど、それが A や B にとっても正しいとは限らない。


980 名前:デフォルトの名無しさん :03/10/19 04:20
>>977
それだと、ふつうはintのアライメントを満たしてるだけだろな。

981 名前:894 :03/10/19 04:34
>>970-972
ぐは。そうなんですか。かなりショック。
mallocにはアライメントは無理だってのは知ってたけど、
C++はせっかくnewに型渡してるのに意味ないじゃん。

情報ありがとうございました。
とりあえず週明けにstroustrup本にでも仕様を聞いてみますかねぇ。家にはない…


982 名前:デフォルトの名無しさん :03/10/19 07:45
>>981
禿本には gcc の独自拡張である __attribute__ が載っているのか?

983 名前:デフォルトの名無しさん :03/10/19 10:08
>>978
> mallocで確保したメモリがどんなアライメント要求も満たすのが前提だから、

処理系が知っているオブジェクトに対してはね。
__attribute__((aligned(64))); なんて物まで考慮に入れられないだろ。きりがない。
つーか、入れられても困るし。

984 名前:デフォルトの名無しさん :03/10/19 12:37
>>981
> C++はせっかくnewに型渡してるのに意味ないじゃん。
そもそもユーザが明示的にアライメントを指定するのは、ANSI C++ 規格の範疇から
外れてるから。

ANSI C++ だと new Foo で呼ばれる operator new の型が

void* operator new(size_t n);

と決まっているので、アライメント値を渡す余地がない。

985 名前:デフォルトの名無しさん :03/10/19 13:51
>>975
private: static void* operator new(size_t);
でOK?

986 名前:デフォルトの名無しさん :03/10/19 14:01
>>985
それなら

public: static void* operator new(size_t n) { return memalign(64, n); }

で良いような気が。

987 名前:デフォルトの名無しさん :03/10/19 15:47
次スレだぁ〜

988 名前:デフォルトの名無しさん :03/10/19 15:47
>>988ゲットだぜ〜

989 名前:デフォルトの名無しさん :03/10/19 15:48
>>989到着〜

990 名前:デフォルトの名無しさん :03/10/19 15:49
次スレ
http://pc2.2ch.net/test/read.cgi/tech/1065535118/


991 名前:デフォルトの名無しさん :03/10/19 15:49
>>990ハァハァ到着ぅ〜

992 名前:デフォルトの名無しさん :03/10/19 15:51
なに〜先越されたーーーーー

993 名前:デフォルトの名無しさん :03/10/19 15:51
おれがスレ立てるからおまいらは、待っててください。

994 名前:デフォルトの名無しさん :03/10/19 15:51
このまま頂上目指すのみ

995 名前:デフォルトの名無しさん :03/10/19 15:53
まだ見ぬ次スレへのリンクが紫色なのなんでだろぉ

996 名前:デフォルトの名無しさん :03/10/19 15:55
C++相談室 part24
http://pc2.2ch.net/test/read.cgi/tech/1066546387/


997 名前:デフォルトの名無しさん :03/10/19 15:55
それはおとズレた事があるから

998 名前:v(^・^)v :03/10/19 15:55
次スレ
C++相談室 part24
http://pc2.2ch.net/test/read.cgi/tech/1066546387/l50

999 名前:デフォルトの名無しさん :03/10/19 15:56
では閉じますか

1000 名前:デフォルトの名無しさん :03/10/19 15:56
C++相談室 part24
http://pc2.2ch.net/test/read.cgi/tech/1066546387/l50


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.