トップページ⇒tech
995コメント307KB

C++相談室 part59

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2007/10/20(土) 16:45:05
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
0153デフォルトの名無しさん2007/11/27(火) 02:31:06
>>152
ありがとうございます
一応アセンブラスレには書き込んだんですけど
こっちでも聞いてみてもいいでしょうか?
0154デフォルトの名無しさん2007/11/27(火) 02:31:09
とりあえずrandomとかrand_sでお茶を濁す。
0155デフォルトの名無しさん2007/11/27(火) 02:33:12
>>151
srandとtime関数使って種別変えてもダメなの?
0156デフォルトの名無しさん2007/11/27(火) 02:38:05
>>152
>プログラムサイコロの再現なんて、ほんとにできたらノーベル賞もんだけどな。
知らなかった

>>155
関係ないはず
本物のサイコロ使うと 6 が連続して出るなんてことも結構な頻度で起こるけど
コンピュータの乱数だと、そんな風にならない…という話だったような
01571462007/11/27(火) 02:38:08
>>148,149,154
ありがとうございます。
分母を最小公倍数で消して
1 4
2 1
3 1
とした上でrandom関数にmax6min0で返り値吐かせて
0〜4なら1を、4〜5なら2を、・・という風にしようかと思います。
返り値の組は変動するのでswitchには乗せられないと思ったので。。
0158デフォルトの名無しさん2007/11/27(火) 07:12:58
>>156
サイコロのかわりに (rand() % 6) + 1 なんてしてると、そんなことになりやすいかもね。
C FAQ にある方法使えば、値域が十分小さいときにあんまりひどい結果にはならないと思うよ。
0159デフォルトの名無しさん2007/11/27(火) 10:41:50
STLのmapを2重に使う場合インサートはどうやってやればいいんでしょうか
map<string, map<int,int> > a;
こんな感じでKeyをstringとintにしたいんです・
使うときa["test"][100]++;という具合にカウントしていきたいんですが
0160デフォルトの名無しさん2007/11/27(火) 10:57:04
普通にinsertできるが、コンテナの中にコンテナはどうかと……
Keyをstringとintの構造体かクラスにして、Compare指定したらどうだろ
01611592007/11/27(火) 11:10:04
>>160
ありがとうございます。
では自分で自作する方針で行きたいと思うのですが
Compare指定について勉強するサイトを教えていただけませんか・・
(浅いものでコンペア指定という語を初めて聞きました)
0162デフォルトの名無しさん2007/11/27(火) 11:41:24
サイトが見当たらなかったので、使用してるSTLのソースを参考にしてみると良いかも

こんな感じに:
template <class T> struct less_key2 {
bool operator()(const T& s1,const T& s2) const { return s1.first < s2.first && s1.second < s2.second; }
};
typedef std::pair<std::string,int> Key2;
std::map<Key2,int,less_key2<Key2> > a;
01631592007/11/27(火) 12:17:04
返事遅くなりました!
すみません、わざわざソース探していただいて。
参考にしつつ考えてみます!ありがとうございましたm(__)m
0164鈴木2007/11/27(火) 13:12:56
MiniDumpWriteDump をつかって、Dumpを出力しているのですが、
どのようにしてファイルの中身は見れるでしょうか?
0165デフォルトの名無しさん2007/11/27(火) 14:08:36
>>164
仕様にそんな名前のものはありません。環境依存スレにでもどうぞ。
0166鈴木2007/11/27(火) 14:56:16
>>165
仕様って何ですか?
C++って1つじゃないんですか?
0167デフォルトの名無しさん2007/11/27(火) 15:02:55
>>166
C++ に MiniDumpWriteDump などというものはありません
Windows API の話は↓へ

Win32API質問箱 Build59
http://pc11.2ch.net/test/read.cgi/tech/1194701996/
0168デフォルトの名無しさん2007/11/27(火) 15:03:42
MiniDumpWriteDumpはWindowsのAPIであって、
C++言語の話ではないってこと
0169デフォルトの名無しさん2007/11/27(火) 15:03:52
>>166
寧ろ、初心者スレへどうぞ。
0170デフォルトの名無しさん2007/11/27(火) 15:05:08
>>165
こういうレスする奴って性格悪そうだな
普通に誘導すりゃいいじゃん
0171デフォルトの名無しさん2007/11/27(火) 15:06:34
このスレに人がたくさん居ることに驚いたぜ
01721652007/11/27(火) 15:12:25
>>170
私の性格を云々したいのなら、雑談スレへどうぞ。
どうせそちらもチェックしていますから。
0173デフォルトの名無しさん2007/11/27(火) 15:37:44
>>170
鼻から悪魔を召喚したいのですがどのスレが適切でしょうか?
0174デフォルトの名無しさん2007/11/27(火) 15:40:57
規格書を読んでundefinedって書いてあることを片っ端から試していくと良いです
0175デフォルトの名無しさん2007/11/27(火) 16:03:55
>>165
と
>>167、>>168
0176鈴木2007/11/27(火) 20:40:23
>>167
ありがとうございます

逝って来ます
0177デフォルトの名無しさん2007/11/28(水) 01:03:23
>>162
なんか初心者スレに似たような比較関数で嵌ってる奴いたな。同一人物か?
ちゃんと Strict Weak Ordering にしないとダメでしょ。
0178デフォルトの名無しさん2007/11/28(水) 09:54:12
>>177
Strict Weak Ordering ですが、>>162の例で言うと
どういう規則になるんですか?

s1.first < s2.first && s1.second < s2.second

これがStrict Weak Orderingを満たしているということは
どういう意味?こういうのは直感的に分かるもの?
0179デフォルトの名無しさん2007/11/28(水) 10:01:11
s1.first < s2.first && s1.second < s2.second

なんかこれ違う気がする。。
s1.firstとs2.firstが一致した場合、secondを調べないで
falseを返すことになるけどいいのかな?条件が複数あると
混乱してくる。
0180デフォルトの名無しさん2007/11/28(水) 10:26:48
if (s1.first != s2.first) return s1.first < s2.first;
return s1.second < s2.second

が正しい。

というか、 std::pair<T, U> は標準で比較演算子持ってるから
基本的に自分で書かなくてよい。
0181デフォルトの名無しさん2007/11/28(水) 10:49:55
>>180
なるほど。

例えばboostのtuple使った場合、Strict Weak Ordering は

if( t1.get<0>() != t2.get<0>() ) return t1.get<0>() < t2.get<0>();
else if( t1.get<1>() != t2.get<1>() ) return t1.get<1>() < t2.get<1>();
else if( t1.get<2>() != t2.get<2>() ) return t1.get<2>() < t2.get<2>();
・
・以下続く
・
となるんですか?
0182デフォルトの名無しさん2007/11/28(水) 11:00:13
>>181
汎用的なコードにするためには、 operator != が定義されていない場合も考慮して
↓のようにしたほうがいい。これなら operator < しか使わない。

if( t1.get<0>() < t2.get<0>() ) return true; else if( t2.get<0>() < t1.get<0>() ) return true;
if( t1.get<1>() < t2.get<1>() ) return true; else if( t2.get<1>() < t1.get<1>() ) return true;
if( t1.get<2>() < t2.get<2>() ) return true; else if( t2.get<2>() < t1.get<2>() ) return true;
・
・以下続く
・
return false;

ポインタが入ってることを考えると厳密には std::less を使わないといけないんだけど、
激しくメンドイ。
01831822007/11/28(水) 11:00:55
ミスった。行末の return true は return false の間違い。
0184デフォルトの名無しさん2007/11/28(水) 11:01:59
>>181
辞書式比較を実装するならそう。
(ただし、型によっては != 演算子を実装してないかもしれないので
 そこは回避する必要があるかも)

ただ、 strict weak ordering を満たす順序づけは一通りではないので、
別のやり方で順序を定義してもいい。
一般には、以下の条件が満たされる比較順序なら何でもいい。
  ある型の値 x, y, z に対して
    1. x < x は false
    2. x < y が true ならば y < x は false
    3. x < y と y < z が両方 true ならば x < z も true
    4. x < y, y < x, y < z, z < y が全て false ならば x < z と z < x も false
0185デフォルトの名無しさん2007/11/28(水) 11:18:29
4つ目の条件の意味がよくわからない
0186デフォルトの名無しさん2007/11/28(水) 11:23:00
>>185
書き換えれば、x == y, y == z が言える状況なら、 x== z も言えないといけないということ。
x < y, y < x がどちらもfalseなら1.から当然、x == y と言えるから。
0187デフォルトの名無しさん2007/11/28(水) 11:24:07
x < y かつ y < x ってのは x と y が等価(equivalent)であるということ。
このことを x≡y と書くとすると、4番目の条件は
    x≡y かつ y≡z ならば x≡z
と書き換えられる。

要するに、等しい連中同士を比べたら必ず等しくなってないと駄目だってこと。
0188デフォルトの名無しさん2007/11/28(水) 11:32:40
>x < y かつ y < x ってのは x と y が等価(equivalent)であるということ。
惜しい。この説明だとおかしい。
0189デフォルトの名無しさん2007/11/28(水) 11:44:25
>>182
!= は < で表現できるから、!= が定義されていない場合がある
ということですよね?

この例の場合>>184の1の条件と2の条件を使ってるということですね。
確かEffectiveSTLにStrict Weak Oderingの一つとして比較対象が一致
した場合は常にfalseを返すことが必要と書かれていました。これは、
>>184の1の条件ということですね。

奥が深いです。

みなさん、どのような書籍を読まれてるのですか?
0190デフォルトの名無しさん2007/11/28(水) 11:47:02
>>188
!(x < y) かつ !(y < x) が true かつ true ならば
つまり『一方が他方の前にあるということはない』
と解釈しました。
0191デフォルトの名無しさん2007/11/28(水) 11:47:27
>>177
それ書いたの俺だ、しかも比較文を間違えてるね
>>159さん、巻き込んだみんなもごめん

演算子はoperator<とoperator==は実装されていると思うけど、
他の人が言うとおり、operator==(!=)は極力避ける方向で>>162の比較は下になります

if (s1.first < s2.first) {
 return true;
} else {
 if (!(s2.first < s1.first)) {
  return s1.second < s2.second;
 } else {
  return false;
 }
}
0192デフォルトの名無しさん2007/11/28(水) 11:55:19
x != y を < で表現した場合、

!(x < y) && !(y < x)

ということで正しいですか?
01931912007/11/28(水) 12:04:06
分かりにくそうなので修正です。

if (s1.first < s2.first) {
 return true;
} else {
 if (!(s2.first < s1.first)) {//if (s1.first <= s2.first) {
  return s1.second < s2.second;
 } else {
  return false;
 }
}

>>192
!(x < y) && !(y < x)
(x >= y) && (y >= x)
(x > y) || (x == y) && (y > x) || (x == y)
(x > y) && (y > x) || (x == y)
(x == y)
0194デフォルトの名無しさん2007/11/28(水) 12:06:29
(x > y) || (x == y) && (y > x) || (x == y)   …×
((x > y) || (x == y)) && ((y > x) || (x == y)) …○
0195デフォルトの名無しさん2007/11/28(水) 12:06:46
>>193
>(x > y) || (x == y) && (y > x) || (x == y)
間違い。
0196デフォルトの名無しさん2007/11/28(水) 12:48:14
assert マクロって必ず assert (x) を !!x で評価してくれるのかな。
ってのは、クラスに ! 演算子をオーバーロードしておけば
そのインスタンスを assert () に渡せるかなと思って。
一応 VC8 見たら !!x で評価してたけど、処理系依存?

クラスの内部状態が整合性ある状態かどうかを自己診断して
失敗なら true、成功なら false 返す処理を ! 演算子で
やろうと思ってます。

えと、なんか気持ち悪いけど失敗なら「true」でいいんだよね・・
0197デフォルトの名無しさん2007/11/28(水) 12:51:27
operator ! よりも operator bool のがいいんじゃないかと思う
0198デフォルトの名無しさん2007/11/28(水) 13:09:57
使うならsafe bool idiom使おうね…
01991962007/11/28(水) 15:38:24
ios_base でも

bool operator!() const{
  // test if no stream operation has failed
  return (fail());
}

ってやってるし、「ダメ」なときに真を返せばいいのかなぁ。
02001962007/11/28(水) 15:39:41
>>197-198
リロードせずに書いてしまった・・・
safe bool idiom ってなにぃ??
ググリマス。
0201196のチラウラ2007/11/28(水) 15:44:55
http://www.artima.com/cppsource/safeboolP.html
02021962007/11/28(水) 18:05:50
safe bool idiom って boost の中でも使われている
みたいだけど、上のサイトにのってるテンプレートの
コード自体は取り込まれていないの?
0203デフォルトの名無しさん2007/11/28(水) 18:17:56
>>199
basic_ios<>でもoperator boolではなくて
operator void*() constだからな。
ポインタとboolの暗黙の変換を利用して真偽値の判定を行う。

cin >> x;
if(cin) { ... }
0204デフォルトの名無しさん2007/11/29(木) 07:53:55
およそ 500 個の cpp ファイルからなる無駄に汎用的なライブラリの開発に関わってるんですが、
モノシックなヘッダを1つ include すれば使えるようにするのと、
500個のヘッダを必要になるたび一つ一つ include してもらうのと、
あるいは両者の中間と、それぞれどんな長所や短所があるでしょうか?
0205デフォルトの名無しさん2007/11/29(木) 08:33:58
500個のヘッダと、それらをすべてincludeするヘッダを一個作れば問題解決
0206デフォルトの名無しさん2007/11/29(木) 10:11:45
これコンパイルエラー(C2059:構文エラー'{')になるんですけど、どうすればいいですか?
class CHoge
{
static const char Names[][]
{
"Name1",
"Name2",
"Name3"
};
};
0207デフォルトの名無しさん2007/11/29(木) 10:13:30
あ、= 忘れてた。訂正。
class CHoge
{
static const char Names[][]
{ //ここでC2059
"Name1",
"Name2",
"Name3"
};
};
0208デフォルトの名無しさん2007/11/29(木) 10:14:34
やばいテンパッテル。
これが本当の訂正。すまん。
class CHoge
{
static const char Names[][] =
{ //ここでC2059
"Name1",
"Name2",
"Name3"
};
};
0209デフォルトの名無しさん2007/11/29(木) 10:38:59
C/C++では多次元配列で全ての要素数が不定(自動決定)なものは定義できません。
>>208のように、全ての要素(文字列)の長さが一緒になるとしても、です。

static const char Names[][6] = {
  "Name1", "Name2", "Name3",
};
なら通るんじゃないでしょうか(VC++6.0で確認)
0210デフォルトの名無しさん2007/11/29(木) 11:08:03
いや、classのブロックからはずすとコンパイル通るんですよー。

static const char Names[][] =
{ //ここでC2059
"Name1",
"Name2",
"Name3"
};

class CHoge
{
};
これならOK。でもクラスの静的メンバーとして二次元配列を持ちたいんですが、どうすればいいですか?
0211デフォルトの名無しさん2007/11/29(木) 11:42:34
>>210
クラス宣言内に書くのではなく
CPPファイルのほうに書く
0212デフォルトの名無しさん2007/11/29(木) 11:47:39
staticなメンバは、constな整数型に限りクラス定義中で初期化できる。(9.4.2)
0213デフォルトの名無しさん2007/11/29(木) 11:51:33
const staticな整数値以外はクラス内では書けない。
0214デフォルトの名無しさん2007/11/29(木) 11:56:39
かぶった。すまん。
0215デフォルトの名無しさん2007/11/29(木) 13:18:38
引き続きなんですが、どうやったらcppに定義できますか?

Hoge.h
class CHoge
{
static const char Names[3][6];
};

Hoge.cpp
CHoge::Names[3][6] =
{
"Name1",
"Name2",
"Name3"
};

C2373 Namesが再定義されています。とコンパイルエラーになります。
よろしくお願いします。
0216デフォルトの名無しさん2007/11/29(木) 13:49:14
なんでHoge.cppの方に型を書かないの?
0217デフォルトの名無しさん2007/11/29(木) 13:50:20
>>210-231
ソウイウコトダッタノカ。
早とちりすまん。

>>215のコードだと、cppの方に型指定が抜けてる気がするんだが。
正確には
cont char CHoge::names[3][6](以下略
じゃなかろうか。
0218デフォルトの名無しさん2007/11/29(木) 14:02:05
おお、できた!ありがとう!
0219デフォルトの名無しさん2007/11/29(木) 17:53:37
multimap<int, map<long,int> > みたいなコンテナの入れ子ってできるんですか?
0220デフォルトの名無しさん2007/11/29(木) 18:08:37
できるよ
0221デフォルトの名無しさん2007/11/29(木) 19:58:27
int Nanakano::Check()
{
int hensu;
hensu = (int)toaru_kansu();
return (hensu);
}
ってこれ何やってる処理ですか?
0222デフォルトの名無しさん2007/11/29(木) 20:04:03
この、
(int)関数()
ってのがわかんないです。何ですか?これ。
0223デフォルトの名無しさん2007/11/29(木) 20:13:24
すみません。キャスト変換ってやつですね。
toaru_kansu()が long型の関数だから、無理やり int型に変換してるみたいです。
toaru_kansu()の戻り値をintにして返してるだけの関数のようですね。。これ。
0224デフォルトの名無しさん2007/11/29(木) 20:15:24
int Nanakano::Check() {return (int)toaru_kansu();}
0225デフォルトの名無しさん2007/11/29(木) 20:21:06
return
の引数って
()
をつけてもつけなくてもいいんですか?
0226デフォルトの名無しさん2007/11/29(木) 20:22:12
returnは関数じゃないので、引き数なんてありません。
0227デフォルトの名無しさん2007/11/29(木) 20:23:17
むしろ、つけちゃダメ

retrun(0) って関数を呼び出しちゃうときがある
0228デフォルトの名無しさん2007/11/29(木) 20:42:14
>>227
わかりました。ありがとうございます。
>>226
return
のあとの数字をなんというのでしょう?戻し値?
0229デフォルトの名無しさん2007/11/29(木) 20:44:28
coutとかで画面に出力した文字を簡単にファイルに記録することなんてできる?
0230デフォルトの名無しさん2007/11/29(木) 20:47:53
戻り値、返り値、返値

好きなの使え
0231デフォルトの名無しさん2007/11/29(木) 20:52:11
>>229
たとえばこんなのどうでしょ「a.exe > out.txt」

Cならstdoutをファイルでrefopen(こんな名前だっけ?)すればいいけど
iostreamも基本、同じかな?
0232デフォルトの名無しさん2007/11/29(木) 21:07:46
>>231スゲーーーーーーーーーできました。
ありがとうございました。
0233デフォルトの名無しさん2007/11/29(木) 21:22:08
ifstreamクラスでテキストファイルを読み込む際に、
consoleアプリで行った場合には問題なく動くのですが、DLLとして作成すると同じコードなのにファイルの読込に失敗します。
原因わかりませんか?
0234デフォルトの名無しさん2007/11/29(木) 21:25:46
エスパーすると、実行時のパスが違うというオチでは
0235デフォルトの名無しさん2007/11/29(木) 21:30:50
>>234
excel VBAでDLLを読み込んでいるのですが、実行時のパスってどこにあるんでしょう?
exeファイルの場所??
0236デフォルトの名無しさん2007/11/29(木) 21:39:33
>>235
Excelのある場所になるのかのぉ?
悪いこと言わないから絶対パスですればよろし
0237デフォルトの名無しさん2007/11/29(木) 21:39:46
C:\Documents and settings\〜 とか、そのへんの予感
0238デフォルトの名無しさん2007/11/29(木) 21:48:30
作戦1 : ファイルの絶対パスまで含めてみた
 → 変なエラーがたくさんでて終了

作戦2 : パス通してみた
 → 結局読み込めない

がーーー意味がわからないです…。
Consoleでちゃんと読み込めていることにさらに疑問。
0239デフォルトの名無しさん2007/11/29(木) 22:00:23
なめてんのか?
0240デフォルトの名無しさん2007/11/29(木) 22:07:20
>>238
変なエラーってなんだよw
0241デフォルトの名無しさん2007/11/29(木) 22:23:20
>>240
ソースは全部会社にあるので確認ができないわけです…
0242デフォルトの名無しさん2007/11/29(木) 22:41:47
>>230
サンキューサー!!!!
0243デフォルトの名無しさん2007/11/29(木) 23:05:28
>>240
俺のエスパーはたぶん \\ だと告げている
0244デフォルトの名無しさん2007/11/29(木) 23:13:30
うーん・・・

a.cpp
 namespace a
 {

 void func()
 {
 }

 } // namespace a

といった、名前空間内にある関数を、他のファイルから参照する方法は無いんですかね?
名前空間に閉じ込めてなければ、
extern void func();
でいいんですけど…
0245デフォルトの名無しさん2007/11/29(木) 23:17:57
え?
namespace a{ extern void func(); };
でいいんじゃないの?
0246デフォルトの名無しさん2007/11/29(木) 23:25:59
namespace a{ extern void func(); };
で宣言、
a::func();
で使う。
0247デフォルトの名無しさん2007/11/30(金) 03:41:57
>>245,246
(・∀・)ありがとう!

分かってみると単純ですね(´・ω・)お騒がせしました。
0248デフォルトの名無しさん2007/11/30(金) 10:28:07
ラッピングって何ですか?
「この関数はラッピングしてるだけ」ってのは、その関数は別の関数を呼んでるだけで処理をやってない
って意味でしょうか?
0249デフォルトの名無しさん2007/11/30(金) 10:33:03
adapter patternでぐぐれ
0250デフォルトの名無しさん2007/11/30(金) 10:38:39
ある関数をプロトタイプ宣言しているヘッダファイルは見つけたんですが、
そのヘッダファイルを開いても意味不明の構造体が並んでるだけで、
その関数の処理自体がどこにも書かれていません。
この関数はどこにあるのでしょうか?

printf()関数などもそうですが、中身がどこにも書かれてなくても使えるものなのでしょうか?
その場合、その関数の使い方などはどこで知ったらいいですか?
0251デフォルトの名無しさん2007/11/30(金) 10:42:12
>>250
ふつうは、ライブラリの中にコンパイル済みのコードが入っている。
Windowsだと 〜.lib 〜.dll、UNIX だと lib〜.a lib〜.so とか。

使うだけなら、そのソースは必要ない。使い方はマニュアルを読む。
0252デフォルトの名無しさん2007/11/30(金) 10:42:53
static link library
使い方はドキュメント見れとしか言えないね
でも引数と戻り値、概要、例外安全性、計算複雑性(?)等のインタフェースが分かったらそれで使えるでしょ
■ このスレッドは過去ログ倉庫に格納されています