C++相談室 part133
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part132
http://mevius.5ch.net/test/read.cgi/tech/1507561894/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.102【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1509780815/
■長いソースを貼るときはここへ。■
http://codepad.org/
https://ideone.com/
[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured つかな、使ってもないのに使用感を予想で語るの止めい。
そりゃ話がループする。
他言語には普通にあるんだし、使ってる奴のレポートを待てばいいんだよ。
利点は、フィールド←→メソッドを変更するときに、記述変更が少なくて済むことだ。
場合によっては戻すこともあるから、その時も助かる。
従って、アジャイルで既に動いているコードを変更しまくるときには便利だが、
ウォーターフォールで基本書いて終わりなら大してメリットはない。()が付くだけだ。
これとは別に、JavaScriptの場合はフィールドとメソッドを区別してないので、オーバーヘッド無しの遅延評価にも使える。
(プロパティ《関数ポインタ、ここで遅延評価する》をフィールド《遅延評価の結果》で直接上書きできる)
C++でこれをやる場合、オーバーヘッドが生じるし、そもそもメソッドコールでいい。
結果、C++には記述上のメリットしかなく、
これはIDEが進歩してリファクタリング出来るようになれば解消する話でもある。
だからそれを待つ、という作戦もありだろうし、
それ以前にIDE側のプリプロセッサでpropertyをサポートしてしまえ、ってのもありだと思う。
まあ、あれば便利程度で、あまり本質的ではない機能なのも事実だ。 お前がそう思うならそうなんだろう
お前の頭の中ではな
貴様の意見も机上の空論でしかない そんなにつぶし合いしたいかね。
収集しようとしてるのに。 >>537
C++を他言語にしたがるやつはどこにでも湧くダニみたいなもんだ
#define begin {
#define end } >>537
なぜ爺は終わった話をクドクド繰り返すのか c++でIF公開するときはメソッドに統一する、でおしまいの話なのにな。 文句だらだらなら、GCCを自分で仕様を追加しちゃえよ! 自分で仕様を追加したGCCとか>>540のマクロとたいして変わらんくない?
いや公式GCCにアクセプトされるなら話は別だけど 追加する仕様によるな
禿がCに「追加した」機能はマクロじゃ済まない そんなにプロパティ欲しいとは思わんが、単純な値操作ならメンバの参照返すメソッド作れば事足りるんじゃね?
それよりconst地獄ってホントにあるの?
const使いまくってて体感したことないんだけと。 メンバの参照を返したらprivateにしている意味が完全に失われるぞ >>547
上流が const を渡してきたら、下流は逆らえない、ってことでは? 自作クラスのメンバ関数にconst全く付けてないタコが聞きかじりで中途半端に付け始めて
「メソッド呼べない!ムキー!このconstってやつ使えねー」ってパターンが大半だと思ってる const地獄になるってことはそのコードが間違ってるって事だからな
全部直せ >>547
本気で言ってるなら、それは経験が足りない 副作用の少ないきれいな設計ならconstだらけになるはずだが No.1
1 2 3 4 5
2 3 4 5 6
No.2
1 2 3 4 5
2 2 2 2 2
3 3 3 3 3
No.3
3 4 5 6 7
:
:
No.n
というtxtファイルがあり。No.〇の次の行に整数が記入されている(何行あるかわからない)
整数の左からx1[ i ][ k ]、y1[ i ][ k ]、x2[ i ][ k ]、y2[ i ][ k ]、A[ i ][ k ]の配列にそれぞれ書き込み
もし次の行整数があればi+1をしまたそれぞれの配列に整数を書き込む
もし次の行に整数がなければ(No.の行)k+1を次の行にいき整数をそれぞれの配列に書き込む。
これをNo.nまで繰り返す。
このプログラムをfopenを使ってプログラムどなたかつくってくれませんかー? ヒント。
いずあるふぁっていう関数どっかにあるから、先頭にアルファベットがあったらスキップや。
それと宿題スレって落ちたの? const指定って下流が対応してないのに上流からやり始めるのは愚だよね プロパティよりも、deleteするとコンパイルエラーになるポインタが欲しい。 >>561
std::shared_ptr<int> a{std::make_shared<int>()};
delete a; //C2440 スマポも「ポインタ」とは言うけどさぁ
deleteの文脈で言っているんだから、オブジェクトは想定外だわ。 所有権のないスマポ(?)ならstd::observer_ptrがもうすぐ入るから待っとけ ところでスマポのコンストラクタの書き方ってどっちがいいの?
class Foo
{
std::shared_ptr<Bar> bar;
Foo(): bar(new Bar(42, 100.5, "xxx")){}
Foo(): bar(std::make_shared<Bar>(42, 100.5, "xxx")){}
};
下の書き方されてるのよく見るけどこれって
「newがあるのにdeleteがない!111」って発狂するアホコードチェッカを黙らせる以外にメリットなんかあるの? あーなるほど
new隠しだけのための砂糖だと思ってましたありがとう
ということはunique_ptrの場合はメリットなしでいいんですかね 俺もmake_uniqueはいらねーよなぁって思ってたけど使った方が例外安全なんだとよ point cloud libraryというライブラリを読んでいます。
kdtreeクラスはsearchクラスをパブリック継承しており、
kdtreeクラスの冒頭で、searchクラスのデータメンバやメンバ関数の一部をusingしています。
これはどういう意味があってやっているのか教えて頂けないでしょうか。 IO2D楽しみだなー。
ウニファイドコールシンタックス復活しないかなぁ。 質問です。
#include "classB.h"
class A{
private:
B* b;
public:
void set(B* b){this->b=b;}
B* get(){return b;}
};
クラスAのメンバーにクラスBのポインタとアクセサがあります。
しかし、set()を使わずに、get()を使ってメンバーにアクセスできてしまいます。
例:a->get()=b;
ポインタではなく、複製したインスタンスを返すことも考えたのですが
クラスBのサイズが非常に大きいため、
可能であれば複製はしたくありません。
どうかご助力をお願い致します。 B* b = nullptr;
B* get(){ assert(b != nullptr); return b;}
こうでもしとけばいいよ >>576
const B* get() { return b; }
あとこうでは
*(a->get()) = b; エスパーだがポインタみたいな動作させたいなら operatorー>() を定義すりゃいいけど上の説明だとなにがやりたいのか具体的にわからないね >>577-582
ありがとうございます!
なるほどconst、普段しっかり使っていないツケが来ましたorz
ただ、そのままだと代入できなかったので、勉強してきます。
ありがとうございましたm( _ _)m
>>580
すみません、ご指摘の通りです。ありがとうございます! Bがなんだかわからないけどsetがものすごくまずいように見える [][] [] [][][][] [][] [] [][][][][
[ ][] [ gtkmmググっても英語含めて17ページしかないんだわ(´・ω・`) オブジェクトの内部データへの変更を許すフリーパスを外に与えるようなsetterやgetterはNG、
しかしあまり杓子定規にそれを言い立てるとファイルハンドルとかもgetterで返して良いかどうかビミョーに…
ファイルはオブジェクトの内部データではないお客様という解釈で乗り切る? いいわけないだろ
教条主義にとらわれていると
そういうことがわからなくなる フレンドクラスに見せるようにする方が例外扱いが明記される分だけマシ >>295 >>292
accelerated c++ をぼちぼちやっています。
>>295 にもバグがあり、正しくは
https://ideone.com/sK4aJ2
一行を最後まで読んでしまったのなら、即座にループを抜けないといけない
なんだか最近 while() の使い道がなくなってきたように思えるのです…いつも for(::) { break; } ばかり書くようになってしまった… 停止性を担保するのは良いことだと思うが。
結局無限ループからのブレークしか使ってないなら頭整理してWHILEに置き換えるようにするなぁ。 >>593
停止性の確認を行った後、余計なことを一切してはいけない、という制約が加わると
途中判定の break 脱出以外に手がない、と考えています
あまり思い出したくないんですが、DOS/Windows の findfirst/findnext なんかも似た類かと >>593
ああ、こういうのはアリでしたね
コメントありがとうございます。
https://ideone.com/9r8rZe アプリケーション上で確保されたヒープ領域を追跡したいです。
operator new/delete と allocator を弄ればできると思い調査していたころ
「プログラミング言語C++ 第4版」P997 に
「標準ライブラリのすべてのコンテナは、newによってメモリを確保して、deleteによって解放するデフォルトアロケータを(デフォルトで)もっている」
と書かれていました。つまり、new をグローバルでオーバーロードすれば追跡可能です。
実際、手元のコンパイラでは std::vector のメモリ確保と解放を追跡できました。
ここまでの内容は規格で保証されている事柄ですか?
実際のアプリケーションに組込むことを考えています。 メモリの確保形式はさすがに実装依存でしょ。
最近リーヌスがブチ切れたらしいけど。
メモリーオーダーコンシウムとかの話は今やってるところ。 >>596
>アプリケーション上で確保されたヒープ領域を追跡したいです。
つgperftools >>596
std::allocator<T> (The default allocator) についての [allocator.members] で規定されてる。
> Remarks: the storage is obtained by calling ::operator new, but it is unspecified when or
> how often this function is called.
標準コンテナにアロケータを指定しなければ std::allocator が使われるから、それでいける。
「実際のアプリケーション」に変なものが混ざってなければね。 アロケータ自作してスパイアロケータとか作ればそれっぽいことはできるね。
標準コンテナに限っては。 >>576
ポインタを返さずに、ハンドルクラスを定義してそのオブジェクトを返す。 >>596
グローバルnew/deleteのオーバーロード自体は、規格で許されてるので合法。
ただ、注意深くやらないと吹っ飛ぶ。
とある処理系の標準ライブラリで、ユーザー回避不可能な不具合に当たったこともあった。 596です
規格での確認と該当箇所のコーディングを確認しました
ありがとうございました! sleep_untilで「何秒後」ではなく「何時に」という絶対時刻を指定する方法なんだけどさ
mktimeとfrom_time_tを使う方法しかないかね? なんかダサくてやなんだけど IDE:Visual Studio Express 2015 for Windows Desktop
浮動小数点モデル設定:Fast Math
コンパイルモード:Release
wWinMain関数内で
wchar_t str[ 16 ];
DirectX::XMMatrixOrthographicLH( 1.0f, 1.0f, 0.0f, 1.0f );
for( int i = 0;; i++ )
{
float f = i;
if( f > 0.0f ) break;
swprintf_s( str, L"%f", f );
}
と書くと、swprintf_sの結果が、期待される0.0ではなく、-0.0になります。
swprintf_sの行と上のif文の行を入れ替えると、0.0になります。
XMMatrixOrthographicLHがなかったり、Debugモードだったり、
Fast MathではなくデフォルトのPreciseだったりすると、
行の入れ替え関係なく0.0。
-0.0になるときは、何が始ま・・・起こってるんです? コンパイラ固有のことなんか聞かれても誰も分からないと思うぞ >>607
floatの符号部が0だったり1だったりしてるのかと
最適化でswprintfだけが残って、fの値は+0.0f以下のゼロということで-0.0にしてくれてるのかなあ >>608
やっぱそれですよね(汗)
>>609
やはりそうですか・・・。
詳しい方なら、何が起こっているかだいたい読めたりしないかなと期待しましたw
>>610
たしかに、符号ビットがコロコロしてそうな感じですよね。
ちなみにif文で比較する定数は1.0fとか2.0fでも結果は同じになりますので、
swprintf_sだけが残るためではないですね。 Gtkmmは4.0も出たのに、詳しい解説ページは2.4のママ・・・(´・ω・`)
でも俺はAPI見ながら頑張るぜ! 今だとC++でGUIやるならQtがデファクトだと思うからそっちの方がいいんじゃない?
GTK使えと命令されてる立場ならすまん Qtとかでかいしライセンスは高いし謎の独自拡張を使わされるわでかなり使いにくいんだが
そのくせ特別使いやすいわけではない でもネットや本の情報は多そうじゃない?
まあ用途も聞かずに頭ごなしに勧めるもんではなかったなすまんかった io2dまだかー。
ウニファイドコールシンタックス復活せよ〜。 基本的な動作について知りたい
msgrcvは、msgsndされた瞬間にキューがたまるから、キューが追加されたと同時に待機状態をやめて動き出す
これであってる??
あと、msgsndする先やmsgrcvで確認する先はmsggetで動的に確保された番号を知らないといけない
こうであってるかな? システムコールの話ならLinux板にでも行け
なんかのライブラリの話なら知ったこっちゃないわ これ実行すると0と2が表示されるので一応は問題ないですか?汚いとは思うけど。
int main(void)
{
vector<int> vec;
vec.push_back(0);
vec.push_back(1);
vec.push_back(2);
for(vector<int>::iterator ite = vec.begin(); ite != vec.end();){
if(*ite == 1){
vec.erase(ite++);
printf("num: %d\n", *ite);
}else{
printf("num: %d\n", *ite);
++ite;
}
}
return 0;
} >>624
>vec.erase(ite++);
ite = vec.erase(ite); にすべし
あと、次の行のprintfは削除で おっと、質問は問題あるかどうかだった。
結論から言うと、問題はある。
0〜2までではなく0〜3までvectorに入れてから実行すれば、
まともに動作していないのは分かるはず。 >>626
やっぱこうしないとダメですね。
ite = vec.erase(ite);
どうもでした。 一応はこれでもいけるってことですかね?削除した時は次の要素になるという理解でいいですか?
for(vector<int>::iterator ite = vec.begin(); ite != vec.end();){
if(*ite == 1){
vec.erase(ite);
}else{
++ite;
}
} これlistとvectorでも違いました。
listだと++しないと正常に動作せず
for(list<int>::iterator ite = lst.begin(); ite != lst.end();){
lst.erase(ite++);
}
vectorだと++すると上手く動作しない
for(vector<int>::iterator ite = vec.begin(); ite != vec.end();){
vec.erase(ite);
}
でもeraseの戻り値取得するのが一番いいですね。 std::vector::eraseのリファレンスに、こう書いてある。
https://cpprefjp.github.io/reference/vector/erase.html
削除された要素またはそれ以降の要素を指すイテレータや参照は無効になる。
これによると、vec.erase(ite); 実行後にはiteが無効になることになる。
あなたの環境だと、たまたまiteが削除した次の要素になったのかもしれないが、
それがすべての環境で成り立つ保証はない。 >>631
基本的にはvectorは無効になるということですかね。 >>631
そのinvalidationは既に取得してるiteratorに起こるやつでは? >>631
なんか変な説明だね
vector<int> vec{0, 1, 2};
auto ite = vec.begin();
++ite;
vec.erase(ite);
--ite;
cout << *ite; //これでvec[0]にアクセスできそうに聞こえる
内容的にはこういうことなのに
vec.m_head = realloc(vec.m_head, 2 * sizeof(int)); listだとこれで動くと思っていいのかな
for(list<int>::iterator ite = lst.begin(); ite != lst.end();){
lst.erase(ite++);
} >>634
eraseした時点で削除された要素のitrも無効だから--できないと思うけど、
別途確保しておいたitrは有効であるかのように読めるから、確かにおかしいね
>>635
どうやら合法。 ■ このスレッドは過去ログ倉庫に格納されています