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

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

C++相談室 part58

1 :v(^・^)v:2007/09/26(水) 03:41:13
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

テンプレその他 >>2-15 付近参照

前スレ(実質 part57)
C++相談室 part56
http://pc11.2ch.net/test/read.cgi/tech/1185377587/

132 :126:2007/10/03(水) 00:14:05
ありがとうございました。

133 :デフォルトの名無しさん:2007/10/03(水) 01:54:49
マクロ使って、行数と引数を連結させたいのですが、

#define macro( name )\
const char *x = "name##__LINE__";

とかやってもできません。
こんなことは可能ですか?

134 :デフォルトの名無しさん:2007/10/03(水) 02:05:02
__LINE__は定数だからダブルクォーテーションで囲っちゃだめっしょ
で、定数を文字列にするのは単純なマクロじゃ厳しいと思うけど・・・
おとなしく関数にしたほうがよさそう


135 :デフォルトの名無しさん:2007/10/03(水) 02:07:38
一応マクロでこんな感じでいかが?
#define macro( buf, name ) sprintf( buf, "%s%d", "name", __LINE__);

136 :デフォルトの名無しさん:2007/10/03(水) 02:10:53
#define NUM2TEXT_(n)    #n
#define NUM2TEXT(n) NUM2TEXT_(n)

#define macro(name) \
const char *x = name ## NUM2TEXT(__LINE__)


137 :デフォルトの名無しさん:2007/10/03(水) 02:43:41
演算子オーバーロードって副作用完了点のことも考慮しないといけないんですか?
std::cout << "test" << std::endl;
で (a) "test" << std::endl; が先に評価されて、次に std::cout << (a) が評価される、という事態にはならないんですか?

138 :デフォルトの名無しさん:2007/10/03(水) 03:26:56
優先順位の同じ演算子の並びは左から評価じゃなかったのか

139 :デフォルトの名無しさん:2007/10/03(水) 04:07:20
左結合と右結合があってね・・・

140 :133:2007/10/03(水) 05:13:05
ありがとうございます。
>>136さんのは
どういう原理なんでしょうか?

141 :デフォルトの名無しさん:2007/10/03(水) 08:46:05
7**7**7 の下一桁の数字は?

142 :デフォルトの名無しさん:2007/10/03(水) 09:44:47
>>137
多重定義されている場合、通常の関数と同様、
呼出の直前に副作用完了点が現れるので心配は要らない。

<<は左結合だから、まずstd::cout << "test"から取り掛かる。
これは多重定義されているので、std::cout.operator <<("test")という関数呼出に相当。
関数呼出の直前には副作用完了点が来るので、ここまでにstd::coutと"test"が評価される。
と言っても、共に副作用を持たないので何も起きないが。
仮に副作用を持つ式だった場合、通常の関数呼出同様に
<<の左側と右側のどっちのオペランドが先に評価されるかは決まっていない。

std::cout.operator <<("test")の戻り値をrとすると、
次にr << std::endlの評価に掛かる。以下同じ。

143 :デフォルトの名無しさん:2007/10/03(水) 11:51:51
>>140
> 16.3.2 The # operator
> 16.3.3 The ## operator

144 :デフォルトの名無しさん:2007/10/03(水) 13:50:35
>>133
#define XY(X,Y) X##Y
#define MAKENAMEXY(FX,LINE) XY(FX,LINE)
#define MAKENAME(FX) MAKENAMEXY(FX,__LINE__)
というマクロで連結させている例がある。
評価順その他の関係で、間に一段置かないとならないらしい。

145 :デフォルトの名無しさん:2007/10/04(木) 00:31:45
VS2008EEで>>136が正常に動作しないんだけど・・・
コンパイラの仕様かな?

146 :デフォルトの名無しさん:2007/10/04(木) 00:36:58
プリプロセッサの仕様じゃね?とかつまんない事言うね。義務として。

147 :デフォルトの名無しさん:2007/10/04(木) 00:45:12
すみません。継承について質問です。

クラスBaseを基底とするクラスDerivAやクラスDerivBがあるとして、
そこからインスタンスを作成するとすると、

Base* pA = new DerivA;
Base* pB = new DerivB;

となると思います。
そこから、pAもしくはpBから新たなインスタンスpCを作りたいと思っているのですが、
どうしたらいいでしょうか?

単にpA(DerivA)だけであれば、DerivA *pC=*pAだけでいけるのですが、
pAとpB(最終的にはBaseを基底とするクラス全部)にも対応できるものを作りたいので、
どうか力をお貸しください。


148 :デフォルトの名無しさん:2007/10/04(木) 00:53:05
class Base {
public: virtual Base *NewInstance() = 0;
};
class DerivA : public Base {
public: virtual Base *NewInstance(){ return new DerivA; }
};
class DerivB : public Base {
public: virtual Base *NewInstance(){ return new DerivB; }
};

Base *pA = new DerivA;
Base *pB = new DerivB;
Base *pC = pA->NewInstance();
Base *pD = pB->NewInstance();

149 :デフォルトの名無しさん:2007/10/04(木) 00:53:41
Base* pA = new DerivA();
Base* pB = new DerivB();

150 :147:2007/10/04(木) 01:02:02
>>148、149
目からウロコが落ちました。

インスタンスを作成する関数を別途で作ればいいわけですね。
ありがとうございます。

151 :デフォルトの名無しさん:2007/10/04(木) 01:04:17
>>148
DerivA::NewInstanceはDerivA*を返し、
DerivB::NewInstanceはDerivB*を返し、
という具合に、そこは共変にしてほしいな。

152 :デフォルトの名無しさん:2007/10/04(木) 01:06:08
凶変を許したことでできるようになったことってなんだっけ?
なんかの本にかいてあったが忘れた


153 :デフォルトの名無しさん:2007/10/04(木) 01:15:57
>>136
boostにはなんて名前で入ってたっけ

154 :デフォルトの名無しさん:2007/10/04(木) 01:18:23
>>152
pAはDerivA*と分かっているとき、
DerivA* pA2 = static_cast<DerivA*>(pA->NewInstance());
のようなキャストを型安全性を損なうことなく排除できる。

155 :デフォルトの名無しさん:2007/10/04(木) 02:07:15
dynamic_castすれば共変なしでも安全じゃね?

156 :デフォルトの名無しさん:2007/10/04(木) 02:08:25
http://videointroplayer.web.fc2.com/?ii9YN1kO-TK36%+WhqyiIrhz0F110%+Kjtps4byn7a119%+esA5NHPWRF1115%+026mGIi9Z4824%+@1@_KeyboardCrusher

157 :デフォルトの名無しさん:2007/10/04(木) 02:29:39
>153
BOOST_PP_STRINGIZE

158 :デフォルトの名無しさん:2007/10/04(木) 08:19:17
これじゃだめなん?

Base *pC = new DerivC;

159 :デフォルトの名無しさん:2007/10/04(木) 08:20:10
Base *pC = new DerivC(pA);
Base *pC = new DerivC(pB);


160 :デフォルトの名無しさん:2007/10/04(木) 21:28:42
>>155
それだと余計な負荷がかかる。

161 :デフォルトの名無しさん:2007/10/05(金) 01:29:04
俺的c++開発環境構築メモ

目的:最終的にlinuxで動かせるようにしないといけないけどVisual Studio捨てれない

winxpにvmwareいれてゲストOSとしてubuntu7を入れる
ubuntuの/home/srcをsambaで共有できるようにしてホストOSのwinxpからみれるようにする

/home/src = \\ubuntu\src
の下にVisual Studioのプロジェクト作成

makefileはeclipse/CDTで自動生成

あとはemacsでメインのコードの編集するけど、flymakeとか使いつつ
インテリセンスも使えてeclipse/cdtのリファクタリング機能も使える環境のできあがり

162 :デフォルトの名無しさん:2007/10/05(金) 04:20:16
俺がいる

163 :デフォルトの名無しさん:2007/10/05(金) 08:18:16
もう遅いだろうがcoLinuxを薦めてみる

164 :デフォルトの名無しさん:2007/10/05(金) 12:27:41
coMomongaを勧めてみる


165 :デフォルトの名無しさん:2007/10/05(金) 12:59:49
coLinuxの方が便利なの?
速度が速い以外のメリットがないなら、もう乗り換えれない

166 :デフォルトの名無しさん:2007/10/05(金) 15:23:45
coLinuxってkernelのバージョンあがるたびに中身を全消ししないといけないって聞いたのだけど
違うの?

167 :デフォルトの名無しさん:2007/10/05(金) 17:36:55
ヘッダファイルなどで記述したグローバルなstatic変数は,
includeしたソースが複数ある(各ソースではincludeガードが起きずに展開される)
場合も単一の存在となるんでしょうか?
それとも別々の独立した変数となるんでしょうか?

168 :デフォルトの名無しさん:2007/10/05(金) 17:41:00
それをインクルードしたソースファイルごとに別々に作られることになる

169 :デフォルトの名無しさん:2007/10/05(金) 18:02:52
ありがとうございます.
あれ,でもクラス変数などは単一なんですよね?
うーむ,基本の理解が全然出来ていない.

170 :デフォルトの名無しさん:2007/10/05(金) 18:26:17
クラスの static 変数はどこかで1個だけ実体を定義する必要がある。

class A{
 static int x;
};
int A::x;  // <-- これ

2個以上のソースファイルで定義したら、定義が重複してるってリンクエラーになる。
static でない普通のグローバル変数と同じあつかい。

171 :デフォルトの名無しさん:2007/10/05(金) 20:36:51
#includeは単にファイルをくっつけてるものと考えれば理解しやすいかも

172 :デフォルトの名無しさん:2007/10/06(土) 00:19:53
>#includeは単にファイルをくっつけてるものと考えれば理解しやすいかも
くっつけるというのはちょっと違う。単にインクルードするだけ。

173 :デフォルトの名無しさん:2007/10/06(土) 03:48:00
>>169
ファイルスコープの static はクラスメンバやローカル変数の static とは全然
意味が違う。これは理解するとかじゃなくて覚えておく必要がある。

174 :デフォルトの名無しさん:2007/10/06(土) 12:08:54
C の仕様設計ミスとも言われている

175 :デフォルトの名無しさん:2007/10/06(土) 13:25:34
ここで聞いて良いか解りませんが
HTMLのtableタグを抜き出して2次元配列化するのに簡単な方法ありますか?

176 :デフォルトの名無しさん:2007/10/06(土) 13:38:01
簡単な方法かどうかわからんが、文字を読み込みながら解析していきゃいいんじゃね?
表の大きさがあらかじめ分かってるなら楽、わかってなくても確保すりゃできる。

177 :デフォルトの名無しさん:2007/10/06(土) 13:43:54
rowspanとかの扱いが面倒くさいなと(´Д`;)

178 :デフォルトの名無しさん:2007/10/06(土) 14:04:10
>>177
大丈夫、Lynx辺りのソースを見れば書いてあるはずだ。
# 簡単とは思えないが。

179 :デフォルトの名無しさん:2007/10/06(土) 19:44:49
100行くらいあるテーブルで
最後の行にだけ colspan 書いてあったり?


180 :デフォルトの名無しさん:2007/10/06(土) 19:55:07
それは困らんだろ

181 :デフォルトの名無しさん:2007/10/07(日) 22:00:29
Linuxでg++4.1.2を使ってるんですが、簡単なODR違反って、リンカが検出してくれたりしないんでしょうか?

182 :デフォルトの名無しさん:2007/10/08(月) 01:04:43
>>181
簡単なやつならシンボルの重複が発生してリンカのエラーになるよ。

183 :デフォルトの名無しさん:2007/10/08(月) 01:15:15
g++だと、クラステンプレートの中の関数はweak symbolになってしまうようで、
重複しても怒られないんだよね.....

184 :デフォルトの名無しさん:2007/10/08(月) 07:47:24
>>183 それは難しいやつってことで。

185 :デフォルトの名無しさん:2007/10/08(月) 14:08:29
最近C++やったのだけど
ただクラスを作って使うだけでもCよりは使いやすいよね、これ。

186 :デフォルトの名無しさん:2007/10/08(月) 14:10:02
クラスを作らないで使わないでもCよりは使いやすい

187 :デフォルトの名無しさん:2007/10/08(月) 14:12:06
C+関数オーバーロード+テンプレートで作ると意外と強力

188 :デフォルトの名無しさん:2007/10/08(月) 14:14:40
BOOST_PPだけで作ると読めない。

189 :デフォルトの名無しさん:2007/10/08(月) 14:21:37
>>185
関数型や今時のLLの真似をしようとすると
すぐに泣くことになるけどな

190 :デフォルトの名無しさん:2007/10/08(月) 14:55:31
BjarneStroustrup様に感謝しなさい。

191 :デフォルトの名無しさん:2007/10/08(月) 16:51:26
以下のコードがsegmentation faultで落ちます。

#include <boost/regex.hpp>

int main()
{
 boost::regex re("^(..)*\\xA4");
}

(ひらがなを含むEUCコードの文字列の正規表現)


コンパイル/実行環境:
i686, linux-2.6, gcc-4.1.2, boost-1.34.0, -O3オプション

ia64、-O2オプションでも試しましたが、その場合は問題は発生しませんでした。

私はこれ以上調べる知恵を持たないのですが、GCCのバグなのでしょうか?


192 :デフォルトの名無しさん:2007/10/08(月) 17:17:20
ICE? 実行時のSEGV?
boostのバグかもしれんよね。

193 :デフォルトの名無しさん:2007/10/08(月) 17:43:33
とりあえず core から stack trace を見るんだ

194 :191:2007/10/08(月) 18:07:48
GDBで覗いてみたら解決しました。
原因は恥ずかしくて言えません。あまりにも下らないミスでした。
スレを汚して申し訳ありません。


195 :デフォルトの名無しさん:2007/10/08(月) 21:55:59
いや、相談しに来たなら原因言ってから取り下げろって。

196 :デフォルトの名無しさん:2007/10/08(月) 22:02:02
>>194
恥ずかしがることないじゃないか、減るもんじゃなし。
このまま消えたらそれこそスレ汚し。質問に対して考えてくれた人に対して礼を欠く事になるぞ。

197 :デフォルトの名無しさん:2007/10/08(月) 22:17:26
おまえら恥ずかしい原因聞きたいだけだろと

198 :191:2007/10/09(火) 00:44:29
自分でインストールしたboostとシステムの管理者がインストールしたboostがあって、
後者の存在はこの問題を解決するまでは知りませんでした。

自分のboostを使うときは-lboost_regex-gcc41としなければならないのですが、
-lboost_regexと間違えていました。
管理者の用意したboostと何事もなくリンクしてしまうのでミスに気付かなかった。

GDBの出力に /usr/lib... という文字列を見つけて始めてミスに気付きました。



あれ? でもおかしいな。違うboostをリンクしたらそれはそれでうまく動くんじゃないんでしょうか?


199 :デフォルトの名無しさん:2007/10/09(火) 01:01:52
>>198
「違うboost」の何が違うのか調べないと、原因はわからんな。

200 :デフォルトの名無しさん:2007/10/09(火) 01:09:37
別に恥かしいことじゃなかったな。
しかし管理者か。
自分の視野外からバグが入り込むとはまるよな。


201 :デフォルトの名無しさん:2007/10/09(火) 01:29:34
boostって何者ですか? どっかの誰かによって拡張されたものですか?

標準ライブラリではないとは思うのだけど、それなら、
boostを使って記述すると、環境依存(バージョン依存)物とか言って怒る人います?

202 :デフォルトの名無しさん:2007/10/09(火) 01:32:43
怒る人がいるかどうかは、お前の環境依存。会社とか。 >>201

203 :デフォルトの名無しさん:2007/10/09(火) 02:15:23
>>198
原因は措いておくとして。
自分がスーパユーザじゃなくて自前でインストールした
ライブラリとかを利用するときは、-I でインクルードパスを明示するのと、
リンク時には -L でライブラリパスを明示するのを習慣付けておいたほうが
良いで。

204 :デフォルトの名無しさん:2007/10/09(火) 02:22:30
>>198 >>203
実行時のLD_LIBRARY_PATHも忘れずに。

それが面倒なら、boostの場合は、.soでなく.aのほうをリンクしてしまうのも手だ。
-lを使わず、/home/mona/lib/libboost_regex.a とフルパスを書いてしまう。

205 :デフォルトの名無しさん:2007/10/09(火) 12:33:32
boost/regexで日本語扱うにはユニコードに変換しないと駄目なんじゃないの?

206 :デフォルトの名無しさん:2007/10/09(火) 17:23:06
namespaceで区切ってグローバル関数を使うのと
クラスを作ってメンバ関数として使うのと

どちらがパフォーマンスがいいのだろうか?

207 :デフォルトの名無しさん:2007/10/09(火) 17:32:11
>>206
どちらも同じコンパイル単位内に関数の実体があると仮定していいなら、後者の方がインライン展開されやすいので
パフォーマンスが高い可能性がある。但し、コンパイラによっては全く同じになる可能性も高い。

208 :デフォルトの名無しさん:2007/10/09(火) 17:48:35
>>207
ありがとう!
つまり、ソースの読みやすさを優先すればいいって事ですね?


209 :デフォルトの名無しさん:2007/10/09(火) 19:04:01
パフォーマンスは置いといて、こういうのって、
(自分流でも)オブジェクト指向に沿って考えたら自然と決まるもんじゃないの?
それともC++のクラスってオブジェクト指向以外の用途も一般的?

210 :デフォルトの名無しさん:2007/10/09(火) 19:33:22
test

211 :デフォルトの名無しさん:2007/10/09(火) 19:45:35
testy

212 :デフォルトの名無しさん:2007/10/09(火) 19:51:39
testest

213 :デフォルトの名無しさん:2007/10/09(火) 20:02:24
>>209
構造化にしろオブジェクト指向にしろ、ソースのメンテナンス性を上げるための物だと理解してます
グローバルな関数にした方が使い勝手が良ければグローバル関数で処理するし
クラス化した方が使い勝手が良ければクラスを使います

使い勝手というのが、ある場面ではパフォーマンスであったり、ある場面ではメンテナンス性であったりするわけですが
また、メンテナンス性は、ソースの可読性に大きく左右されるので、パフォーマンスが同等であるならば、ソースの可読性を優先するのは自然だと思います


214 :デフォルトの名無しさん:2007/10/09(火) 20:42:41
namespace hage{namespace hoge{
  void func() {}
  }}

struct hage2 {struct hoge2 {
  static void func() {}
    };};

int main() {
  hage::hoge::func();
  hage2::hoge2::func();
}

どちらでも階層を実現できるけど
class struct を使う方法ならアクセス指定もできる
よって選らぶなら後者?…なわけないな

215 :デフォルトの名無しさん:2007/10/09(火) 20:44:08
×選らぶ
○選ぶ

らぶ

216 :デフォルトの名無しさん:2007/10/09(火) 20:48:47
>>213
なるほど、C++初心者だけどOOPに慣れてるから、まずOOがあるものとして考えてたよ
ただ、
> ソースの可読性を優先するのは自然
って考えた時に、オブジェクトとして捉えられる物はクラス化した方がいい場合があるのは当然として、
そうでないものをクラスにまとめることもあるのかな?ってのを疑問に思ったの

名前空間とクラスのどっちを選ぶかは目的の持っている意味で分けられて、
それで結果的に可読性が向上すると思ってるから

217 :デフォルトの名無しさん:2007/10/09(火) 23:08:42
char hoge[5000*5000];
とか書いといて走らせると、hogeがちゃんと確保されないんだけど、
これって当然なんでしょうか。
100*100とかだと大丈夫。
アクセスするとseg faultしちゃう。
newしてやるとちゃんと確保される。

gcc + Linux or OS X

218 :デフォルトの名無しさん:2007/10/09(火) 23:11:37
コンパイラでスタックの量を24MB以上許容してくれるように設定しなさい。

219 :デフォルトの名無しさん:2007/10/09(火) 23:22:40
>>218
ああ、そういうのがあるんですか。
newしてポインタがNULLかを調べるほうが普通?

220 :デフォルトの名無しさん:2007/10/09(火) 23:27:35
とりあえずスタックとヒープの違いについて調べるのが普通

221 :デフォルトの名無しさん:2007/10/09(火) 23:29:53
C++の規格にスタックとかヒープなんてあったっけ?

222 :デフォルトの名無しさん:2007/10/09(火) 23:31:53
ないね

223 :デフォルトの名無しさん:2007/10/09(火) 23:35:58
>>219 標準 C++ で、ただの new がヌルを返すことはありません。

224 :デフォルトの名無しさん:2007/10/10(水) 01:55:15
まぁ規格になくても知っといた方がいいやな。

225 :デフォルトの名無しさん:2007/10/10(水) 21:01:39
Javaでスタックにオブジェクトおくにはどうすればいいの?
もちろん、スレちがいだかんね。

226 :デフォルトの名無しさん:2007/10/10(水) 21:13:13
SomeClass *p = new SomeClass();

SomeClassのコンストラクタの処理が凄い思いとする。
この重い処理中、p は NULL? 非NULL? どちら??
処理系の実装依存なのかな。

227 :デフォルトの名無しさん:2007/10/10(水) 21:53:05
ごみ値。

228 :デフォルトの名無しさん:2007/10/10(水) 21:56:43
VC6やそれ以前を前提に話をしたいならそれ専用のスレに行ったほうがいい。
あれの動作は特殊だからねぇ〜

229 :デフォルトの名無しさん:2007/10/10(水) 22:01:04
スレチ杉てわらってしまった

230 :デフォルトの名無しさん:2007/10/11(木) 12:10:34
SomeClass *p = new(nowthrow) SomeClass();

ってやれば、一応失敗すればヌルポを返す

231 :デフォルトの名無しさん:2007/10/11(木) 13:19:46
そしてコンストラクタが例外を投げるとw

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

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

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