0からの、超初心者C++相談室at TECH
0からの、超初心者C++相談室 - 暇つぶし2ch287:デフォルトの名無しさん
21/06/03 02:59:14.77 Ers5yK+g.net
char は環境依存なので使わないようにする。
unsigned・signed のどちらなのか、分からないため
unsigned char は、0~256
signed char は、-128~127
0~127、7ビットの範囲では、この2つは共通している
signed charは、先頭ビットが1なら、負数となる。
2の補数を調べて
1111_1111・0xFF なら、256か、-1

288:286
21/06/03 03:03:09.44 Ers5yK+g.net
>>287
修正
256 ではなく、255 です
unsigned char は、0~255
1111_1111・0xFF なら、255か、-1
だから、環境依存のchar 型を使っていると、
エラーに、-1を使っていたが、他の環境では255と表示されたりする

289:デフォルトの名無しさん
21/06/03 10:13:20.76 oKNqyVQK.net
むしろ int を期待してる引数に char 渡す時が危険

290:はちみつ餃子
21/06/03 13:38:18.86 ivgy5ZU8.net
char 同士なら符号の有無が違ってもビットパターンは維持された
ままで型を読み替えることが期待できる (言語仕様として保証しているわけではない)
けど、大きな型に変換するときは符号拡張が起こることがあるからだね。

291:デフォルトの名無しさん
21/06/05 22:29:47.19 UR0LV/yo.net
ハーバートシルト『STL標準講座』翔泳社, 1999, p.156-157
のサンプルプログラムで、そのままだとコンパイルが通らないものがあるのですが、
適当にconstをつけていたらコンパイルできるようになりました
しかし、理由がわかりません
どなたかご教示いただけませんか?
URLリンク(ideone.com)

292:デフォルトの名無しさん
21/06/06 01:24:02.19 Lz5dZs8J.net
operator <<のとこでoがconst参照だから、そのoからはconstなメンバ関数しか呼べない。のでそれで合ってる
元のソースが間違ってるか何かだと思う、この仕様は最初からのはずなので

293:
21/06/06 01:44:38.27 xlnMgrm3.net
>>291
set<>::iterator は const をつけていなくても set<>::const_iterator と同じくイテレータ≒ポインタに const 属性がつきます。
だから set<>::iterator p; …①、と宣言した場合の p には「終生」 const 属性がつきまとうことになります。
例えば①の p にポインタ演算子 * を適用して出来た表現「*p」が参照に読み替えることがあれば、その参照は const 参照でなければなりません。
もともと const 属性はポインタにつけて、const 属性のついたポインタに -> 演算子を使って出来たメンバ変数の値を変更しないようにコンパイル時に厳密にチェックする縛りです
c++ における参照は「機械的にポインタを使った書き方に書き直すこと」が可能(…②※)ですから、const なイテレータ(≒ポインタ)から生成した参照は const な参照にならざるを得ないのです
※②は私の持論で、今回のお題でも参照をポインタに全部書き換えてやろうと試行錯誤していましたが、さすがに iostream や set で先に参照として宣言されているものを後からポインタにするのは不可能でした
頑張ってみたけれども、かえって意味不明な URLリンク(ideone.com) ぐらいにしかならなかった、持論は修正しなくてはいけないなあ…
set は重複要素を許さない二分木構造です。二分木構造 set に要素を挿入するときに、要素の大小関係にしたがって二分木の形をくみ上げていきます。
だからすでに二分木に組み込まれてしまった要素が、後からほいほいと要素の内容を変えられてしまっては二分木構造に矛盾をきたし、役に立たなくなってしまう…
だから set にすでに組み込まれている要素をイテレータで走査するときは、そのイテレータ≒ポインタは、メンバの書き換えが不可能なイテレータとするしかないか、と私は考えます
提示していただいたソースを、上に述べた原則にしたがって、この原則に関係ない余分な部分を削り落として書く(あと、ちょっと簡略化もしています)と次のような感じでしょうか。
URLリンク(ideone.com)
friend 略 operator<<(略 C const &obj) { ... }
にならなくてはならないのは set<C>::iterator は set<C>::const_iterator と同じだからです
friend bool operator<(C const &a, C const &b) は set への要素の挿入のときに使う比較関数ですが、比較作業以外に要素のメンバを変えるとか余計なことをさせないために、最初から const 参照で宣言するべきでしょうし、そうなっているみたいですね
しかし、この const 属性はプログラミング 3 年生くらいまでは、かなり分かりにくい縛りであることは、私の経験からもとても理解できます。
ポインタや参照をしっかり理解しないことには、わざわざ自分を縛る const のありがたみもよく理解できないだろうと、私も同情するのです。そういうときは、const_iterator p から作った表現 *p が展開された先の実際の表現を、「*p のコピー・オブジェクトのコピー」にするのがいいでしょう
上記のお題をこの方針で書くとこうなります。
URLリンク(ideone.com)
いろいろ書きすぎたかもしれませんが、上に示した三つのソースコードを研究してみてください

294:
21/06/06 01:58:54.60 xlnMgrm3.net
>>291
>>293
スレリンク(tech板:593番)
593 名前:◆QZaw55cn4c [] 投稿日:2021/03/14(日) 20:13:24.03 ID:uaeFGveg [3/6]
>>590
>C++は未だ*や&、&&、で頭の中がグルグル回ってしまう
これらの「記号」は習得に順序があります。
まず * をしっかり理解します。C/C++ はなんといってもポインタが基本です。
次に参照 & を理解します。参照& を使う場面が出てきたら、これを * を使った書き方に書き直す、という機械的な訓練がいい練習になるでしょう
参照 で返す、という場面でも、①参照返しが出来る場合と、②参照返しはできずせいぜい RVO に期待するしかない場合、の①②二つの違いを明確に即答できるようになるべきでしょう(最近まで私はそれができなかった……)参照& の表現は新しい表現( ranged-for とか) でよく目にしますし、①②は結構重要だと思います
&& は多分最後でしょうね、私も && は良く分かっておらず、というか、分からないから使わないという態度に留まっていますが、まあそれでもなんとかなる気がします

295:
21/06/06 02:07:24.75 xlnMgrm3.net
>>292
operator<<() のストリームじゃないほうの引数は、const 参照ではなくてもいいと思います
今回のは const 参照が要求されたのは、 set のイテレータだから
URLリンク(ideone.com)

296:
21/06/06 02:32:48.87 xlnMgrm3.net
>>293
ソースを貼り付けた一行目がミスっていましたね、修正します。
>しかし、この const 属性はプログラミング 3 年生くらいまでは、かなり分かりにくい縛りであることは、私の経験からもとても理解できます。
>ポインタや参照をしっかり理解しないことには、わざわざ自分を縛る const のありがたみもよく理解できないだろうと、私も同情するのです。
>そういうときは、const_iterator p から作った表現 *p が展開された先の実際の表現を、「*p のコピー・オブジェクトのコピー」にするのがいいでしょう
>上記のお題をこの方針で書くとこうなります。
URLリンク(ideone.com)

297:デフォルトの名無しさん
21/06/06 02:41:34.70 Lz5dZs8J.net
ああ、operator <<のconstも最初付いてなかったのか
それならsetの仕様変更のせいだね
というか昔のままの非constの方が良かったんだけどなぁ
比較演算子自分で書いてるような構造体だと順序変わらない場合もあるんだし・・正直押し付けがましい

298:
21/06/06 03:22:16.34 xlnMgrm3.net
>>297
自分で一から書く分には const に一貫性を持たせて、結果、const が有用に働くように書いていけるかもしれない、とか思うのですが、
他の人の分を取り込むときは、最悪 const_cast を >>291 の言うように「適当にconst_cast をつけていたらコンパイルできるようになりました」とか私も言っているわけでして、私は >>291 を笑うことができません……

299:デフォルトの名無しさん
21/06/06 08:29:50.46 KyPgEn9X.net
一から書いている私ですが、
全てのフォルダ・ファイル・プログラムに一貫して
*と何か名前を付けてプログラミングをしています。

300:デフォルトの名無しさん
21/06/06 08:34:21.45 8VTCuGWY.net
QZ・・・・
C++をちゃんと理解できてないのに無理すんなw

301:
21/06/06 09:27:07.17 xlnMgrm3.net
>>300
>C++をちゃんと理解できてないのに無理すんなw
うん。すっごく認めます!
でもちゃんと理解できていないからこそ、アウトプットもきちんと書くようにして定着させたい、というのもあるんですよ
「教えることは教わること」
>>291 に対する回答としての >>293, >>295 に間違いはないですよね?

302:デフォルトの名無しさん
21/06/06 09:44:11.48 WkbXnMOk.net
意味分からん理屈だな
ずっと前からC++分からないって言ってるよね?
もしかして理解できる頭を持ってないのかな?

303:
21/06/06 13:37:50.42 xlnMgrm3.net
>>302
自己申告なんて当てにしてはいけないのでは?

304:デフォルトの名無しさん
21/06/06 15:27:30.95 fMmzH2Jl.net
文面から必死な感じがヒシヒシと伝わってくるのに
皮肉も理解できないとはさすが厚顔無恥の代表格
誰も認めてくれないから自画自賛するしかないんですね

305:
21/06/06 16:22:05.09 xlnMgrm3.net
>>304
え?必死?思いがけない反応ですね
まあ >>291 の方が提示したソースはハーバードシルトにしては冗長だと思って無駄丁寧っぽく説明したほうがいいかと >>293 をワサワサ書きましたが、それが必死だとは…
よく分かっている方 >>292 に対しては簡潔に私の意見 >>295 を送ってもう十分、仕様変更があったという情報 >>297 をいただいて感謝、というところでしょうか

306:290
21/06/06 22:29:30.82 DvMt5hdj.net
>>292
>>293
どうもありがとうございます
constメンバ関数の理解が不十分だったようです
constメンバ関数はメンバ変数を変更しないという理解だけで、
constオブジェクトはconstメンバ関数しか呼べないことへの
理解が足りなかっため私自身混乱していました
ご説明いただいた内容を足掛かりに理解を深めたいと思います

307:1
21/06/07 07:01:58.64 pWKPTo4/.net
まぁ、いいじゃねぇか、プログラミングなんて何にも知らないってのスレだし。

308:デフォルトの名無しさん
21/06/07 07:48:28.30 c29T7zKX.net
const char* const str[] は文字列アドレスを格納するポインタの配列って意味であってますか?
const char* strは文字列を格納するポインタ?
char str[] は文字配列?
一気に出てきてよくわからなくなって来たので間違えてたら教えて欲しいです。

309:デフォルトの名無しさん
21/06/07 08:39:52.02 xFpLHEPr.net
>>308
だいたいあってる

310:デフォルトの名無しさん
21/06/07 11:12:06.49 BLDePS2Q.net
ちゃんとメモリ確保してから使えよ

311:デフォルトの名無しさん
21/06/07 22:09:28.76 JY7FyEcf.net
>>309
ありがとうございます。

312:デフォルトの名無しさん
21/06/08 23:28:22.97 kZSYpF+Y.net
URLリンク(ideone.com)
103 と115で確保された動的配列のアドレスは別物なんでしょうか?
コピーコンストラクタの動きがよくわからないです

313:デフォルトの名無しさん
21/06/09 02:24:41.44 ZtayyY2i.net
103のarrayはコピーされたものだから別物だよ
てか初っ端から手直しが必要なソースを貼るのはやめろ

314:デフォルトの名無しさん
21/06/09 02:39:16.49 Ih94CWHU.net
スレの主旨的に初心者が初歩的な質問をするのは別に構わんとは思うんだが、
入門書にでも書いてあるようなことはよく読んで勉強したほうがいいと思うぞ。
素人が1レスで答えるよりはちゃんと体系だった解説のほうがわかりやすいよ、常識的に考えて。

315:デフォルトの名無しさん
21/06/09 04:24:03.76 BGdtXEJj.net
>>313
すいません、ヘッダーとかcpp分けてるのどうアップロードすればいいのか分からなかったです
後65行目にcopy(other.m_array, other.m_array + m_size, m_array);とあるのですが何をしてるのか分かりません
本には”第1引数以上第2引数未満のアドレスにあるデータを第3引数の指すアドレス以降にコピーする関数で…とあるのですが
具体的に何をしてる関数なのでしょうか?第2引数の足し算も何なのかよく分かりません。

316:デフォルトの名無しさん
21/06/09 04:43:32.09 ZtayyY2i.net
URLリンク(ideone.com)
こうしたらそのままコンパイル通るやろ
自分のヘッダincludeしてるとこにヘッダの内容貼り付けるだけ
URLリンク(cpprefjp.github.io)
memcpyと似たようなもん(コピーの仕方は違うけど
other.m_arrayの指すアドレスから+m_size分のアドレスまで(未満)をm_arrayの指すアドレスから同じく+m_size未満までコピーしとるだけ
これで分からんならポインタの理解が出来てない
上記のとこだとイテレータとか出てるけどこの場合ポインタなので全部ポインタに読み替えていい

317:デフォルトの名無しさん
21/06/09 04:53:28.23 ZtayyY2i.net
ちょっと誤解招きそうなので補足
m_sizeは個数なのでアドレス値ではないがintのm_size個分アドレスが加算される
このへんは>>314の言う通り入門書嫁

318:デフォルトの名無しさん
21/06/09 14:16:25.82 3Qpbsqp/.net
cpp で socket を読み書きする stream 系の class ってありますか?
boost にはあったと思いますが
標準のはあるんですか?無いですか?

319:はちみつ餃子
21/06/09 16:06:33.34 Ih94CWHU.net
>>318
標準には無い。
が、ソケットに stream のインターフェイスをかぶせることはそれほど難しくはない。

320:デフォルトの名無しさん
21/06/09 22:30:15.61 BwbEIJxn.net
>>316
1引数から2引数で足したアドレスまでを第三引数にコピーしてるのですね
やっと分かりました。ありがとうございます。
頭硬い人はロベール向いてないのかな…

321:デフォルトの名無しさん
21/06/09 23:57:13.88 ZtayyY2i.net
それは良かった
まぁ最初は理解に時間かかるもんだ

322:デフォルトの名無しさん
21/06/10 10:45:51.80 ZbfFyHii.net
>>319
thx
cpp の std にある関数で glibc の様な getpass ってありますか?
標準のは無いですか?

323:はちみつ餃子
21/06/10 14:24:18.43 MOYAWABe.net
>>322
無いよ。

324:デフォルトの名無しさん
21/06/11 14:28:13.59 tB3/M6ll.net
FILE *fp = fopen() で取得した fp を使って
stringstream としてアクセスすることは出来ますか?

325:はちみつ餃子
21/06/11 17:27:01.32 DsaVPusD.net
>>324
直接的に一発で FILE* に stream をかぶせる手軽な方法はないと思うけど、
std::basic_streambuf を継承して setbuf, overflow, sync などをオーバーライドしたクラスを作ればストリームバッファになる。
(普通は std::basic_filebuf も内部的にはそう実装されているはず。)
それをストリームに結び付ければストリームに出来ることは何でもできるよ。
仕様を調べるのがすごくしんどいだろうけど、
実装は (細かいエラーチェックとかを抜きにすれば) 百行も要らないくらいの簡単なものでいけるんじゃないかな。

326:デフォルトの名無しさん
21/06/16 00:59:39.17 QFUk0bjY.net
>>324
fstreamを使えば?
#include <fstream>
#include <sstream>

std::ifstream fs("hoge.txt");
std::stringstream ss;
ss << fs.rdbuf();
fs.close();
それともfstream使えない特殊な環境?

327:デフォルトの名無しさん
21/06/16 16:36:23.72 uJQ6HHCX.net
FILE *fp = fopen(...);
std::ifstream fs(fp);
出来たらいいな

328:デフォルトの名無しさん
21/06/17 21:31:03.90 OB6uOiq6.net
関数へ渡す引数の型を限定したいときどう書くのが一般的ですか?
具体的に言うと符号なしのintだけ受けつけたいんですけど

329:はちみつ餃子
21/06/17 23:54:09.39 Gi/wqrqm.net
>>328
暗黙の型変換を許さないということかな?
それならテンプレートにした上で型に制約を付ければいい。
ここでは C++11 でも通るように書いてみたけど C++20 以降なら
コンセプトが使えるのでもう少し簡単に書ける。
#include <type_traits>
template<class T>
typename std::enable_if<std::is_same<T, unsigned int>::value>::type foo(T) {
}
int main(void) {
int a = 1;
unsigned int b = 2;
foo(a); // これはエラーになる
foo(b); // これは通る
}

330:デフォルトの名無しさん
21/06/18 08:42:03.67 kejK9s3z.net
なんで戻り値voidに限定してんだよボケ餃子

331:デフォルトの名無しさん
21/06/18 11:49:14.92 AVf6Ht59.net
確かにそれで可能だけど、回答が超初心者スレのレベルを逸脱していると思うのですが

332:はちみつ餃子
21/06/18 18:30:00.74 JA4mPV9U.net
>>330
単なるサンプルだからだよ。
>>331
超初心者が相談するという主旨のスレではあるけど、
超初心者には理解できないという結果になることもあるだろうし、
可能であれば相談した結果として初心者から脱したらそれに越したことは無いでしょ。
これで相談がクローズってわけでもないから
もっと深く知りたいってのならわからないところを続けて質問してもらってもいいわけで。
もっと簡単な方法があるならそれを提示するんだけども、なくなくなくない?

333:デフォルトの名無しさん
21/06/18 19:23:19.39 kejK9s3z.net
>>332
アホか
普通のenable_ifの使い方と全く違うお前だけのオナニーコード押し付けて何がサンプルだ
何不必要な制限勝手につけてドヤってんだボケ

334:はちみつ餃子
21/06/18 19:32:07.35 JA4mPV9U.net
>>333
返却値 (または enabler) で制限するのは普通だろ。
むしろ他にどう使えるんだ?

335:デフォルトの名無しさん
21/06/18 19:35:45.29 kejK9s3z.net
>>334
マジで言ってんのか?
#include <type_traits>
template <class T, typename std::enable_if<std::is_same<T, unsigned int>::value>::type* = nullptr>
void foo(T)
{
}
int main()
{
// foo((int)1);
  foo((unsigned int)1);
}
enablerってこれのことか知らんが、お前のコードだと戻り値voidにしか出来んだろってこと

336:デフォルトの名無しさん
21/06/18 19:42:19.79 kejK9s3z.net
>>328
ちなコンセプト版(C++20対応コンパイラが必要)
#include <type_traits>
template <class T>
concept UnsignedInt = std::is_same_v<T, unsigned int>;
template <UnsignedInt T>
void foo(T value)
{
}
int main()
{
// foo((int)1);
  foo((unsigned int)1);
}
(インデントは全角なので注意)
まぁどっちも難しいと思うけど無理に理解せず流した方がいいと思う(それか制限あきらめるか

337:デフォルトの名無しさん
21/06/18 19:43:08.40 AVf6Ht59.net
>>332
いや、お前の言いたいことは分かるよ
ただテンプレートメタプロコードを超初心者にいきなり例示して、「わからないところを続けて質問」して回答を繰り返して、結果的に理解に至るのは何ヵ月後になるんですかと
テンプレートに関する高度な質問が飛び交う中、ここは超初心者スレとして機能するんですかと
この場合>>328が求めているのはドリルじゃなくて穴だと思うよ俺は
どういう背景があってunsigned int以外を受け付けたくないか、を聞くべきなのでは?

338:デフォルトの名無しさん
21/06/18 19:57:29.32 kejK9s3z.net
確かにそうだね
というか自分もテンプレート以外思いつかんかった・・
>>334
なんか変な癖あるから標準的な使い方がすっぽ抜けてたのかね
ボロカス言って悪かった

339:デフォルトの名無しさん
21/06/18 20:01:53.90 zIhiG+wy.net
あんまり詳しくない俺にはこういうのしか思いつかん。
__my_func() は直接呼ばないお約束にしておいて、static_assert で。
template のところは、書き換えは雰囲気でできると思うけど・・・
#include <type_traits>
#include <iostream>
unsigned int __my_func(unsigned int a) { return a * 2; }
template <class T> unsigned int my_func (T a) {
static_assert(std::is_same<T, unsigned int>::value == true, "is not uint.");
return __my_func(a);
}
int main() {
int a = 2;
unsigned int b = 2;
//std::cout << my_func(1) << std::endl; // assert
//std::cout << my_func(a) << std::endl; // assert
std::cout << my_func(1U) << std::endl;
std::cout << my_func(b) << std::endl;
}

340:はちみつ餃子
21/06/18 20:30:53.23 JA4mPV9U.net
>>335
> お前のコードだと戻り値voidにしか出来んだろ
なんか変なこといってると思ったらそこがすれ違いか。
std::enable_if のテンプレート引数の二個目を省略しなければ何にでも出来るよ。
(std::enable_if の type は void に固定されているわけではない。)
クラスやコンストラクタは返却値がないから enabler を使うんであって、
普通の関数のときは返却値のほうで制御するのが普通だと思うぞ。

341:はちみつ餃子
21/06/18 20:33:26.89 JA4mPV9U.net
>>337
まあそうなったら他に誘導してもいいし、資料を提示するだけで十分だと思った。
ただ背景をもうちょっと引き出すべきというのも確かに必要なことではあったな。

342:デフォルトの名無しさん
21/06/18 20:39:10.69 kejK9s3z.net
そうなんか、そういえばいつも自作alias使ってたから気付かんかったわ
>普通の関数のときは返却値のほうで制御するのが普通
別に戻り値でも引数でもいいが、クッソ読みづらいと思うけどな
あとそれならこういうスレで第2引数省略すんなよ、初心者惑わしたいのか?

343:1
21/06/19 15:34:05.42 kvHrZ2tI.net
ここは中級者が、お互いを煽り合うスレでは無い、ということを理解して欲しい。

344:デフォルトの名無しさん
21/06/19 16:53:11.57 zDrgWeBe.net
引数同じで戻り値だけ違う関数を造って使い訳たい

345:デフォルトの名無しさん
21/06/19 17:01:53.54 xVp2TfT/.net
>>343
俺ははちみつが書くより先に同じこと(enable_if)思ってたけど、このスレには不適切だと思って書くのやめてたんだけどな
あんな不適切で不親切な回答(テンプレートとSFINAEとか、はちみつも使いこなせてないようなものを使う上に戻り値の変更方法も、自身が言ってるコンセプト版も書かない)に怒っちゃいかんのか

346:はちみつ餃子
21/06/19 17:30:35.18 /f53/cxR.net
>>345
そこらへんが少しばかり詳細なら初心者に理解できる内容になるという主張?
少々の書き方の工夫で初心者がわかるように解説できるわけないだろ。
関連知識も含めればちょっとした本一冊分くらいにはなる内容なんだから。
「まずはテンプレートの知識が必要ですね」ということが初心者に対する解で、
そこに至る前にごちゃごちゃしたことを詰め込むのは不親切だと思うわ。

347:デフォルトの名無しさん
21/06/19 17:34:51.32 xVp2TfT/.net
>>344
戻り値だけ違う同名関数は作れないのでテンプレートにするか、引数で戻り値を指定するしかないとおも
template <typename T>
T hoge();
template <>
int hoge<int>() {}
template <>
float hoge<float>() {}
hoge<int>();
hoge<float>();
もしくは
int hoge(int) {}
float hoge(float) {}
?hoge(int());
hoge(float());

348:デフォルトの名無しさん
21/06/19 18:00:39.76 kvHrZ2tI.net
1 + 1 = 1

349:デフォルトの名無しさん
21/08/24 01:28:35.73 WM1jAzNs.net
URLリンク(pastebin.pl)
operator関数の動きがよくわからないんですが
tmp.x = x + p.x;
これの p.xと xとtempはどのオブジェクトのことを指してるんでしょうか?

350:はちみつ餃子
21/08/24 01:50:15.06 MkJE9y3A.net
>>349
operator+ は演算子 + の実体として機能する。
故に p1+p2 は p1.operator+(p2) と書いた場合と完全に同じ。
tmp はもちろんこの関数内で宣言した tmp 変数だし、
p は渡された引数 (この場合は p2) のコピーなので p.x には 6 が入ってるね。

351:デフォルトの名無しさん
21/08/24 02:43:37.56 WM1jAzNs.net
>>350
ありがとうございます。引数がどれに対応してるかわかりました。
p1.operator+(p2) これは何でしょう?

352:デフォルトの名無しさん
21/08/24 03:37:20.26 gGQMgsWd.net
掛け算の*と、
色々を示す*が
同じ*なんで困っていますが、どうしたらいいんでしょうか?

353:デフォルトの名無しさん
21/08/24 03:55:09.38 jikR3Y9f.net
色々ってワイルドカードのこと?
C++においては*は乗算かポインタ関係だけだよ
>>351
p1のメンバ関数として普通にoperator +を呼んでるだけ

354:デフォルトの名無しさん
21/08/24 04:29:07.93 gGQMgsWd.net
ありがとうございます。
c++ のワイルドカード記号ってなんでしょうか?

355:デフォルトの名無しさん
21/08/24 04:33:24.90 jikR3Y9f.net
言語そのものには無いよー
エディタやIDEで検索するのには使えることもあるが

356:デフォルトの名無しさん
21/08/24 04:45:36.01 gGQMgsWd.net
教えてもらって、勉強になりました。
ありがとうございました。

357:デフォルトの名無しさん
21/08/24 07:22:03.54 WM1jAzNs.net
URLリンク(pastebin.pl)
クラスの型変換と型変換用のコンストラクタの意味が全く分からないのですが
これをすると何が得なのでしょうか?10行目は普通のコンストラクタに見えますがなぜ変換用?
入門書に載ってるコードなのですがエラーで動作もせず何がなんだか分かりません…

358:デフォルトの名無しさん
21/08/24 15:23:13.01 jcrsR8Np.net
2つ目のprivateはpublicの間違いじゃね?
あと変換は、単に引数一つだけを受け取るコンストラクタは
自動的に?暗黙のキャストにも使われる、というだけ(それを禁止する方法もあるが

359:デフォルトの名無しさん
21/08/25 07:15:15.42 dwOa++JV.net
>>358
おかげさまで動きました。ありがとうございます。
でもいまいち型変換の意味が分からないのですが
operator 型名()return 変数を定義するとどの変数にも代入出来るようになるってことですか?

360:デフォルトの名無しさん
21/08/25 15:58:08.24 3/bOIe3o.net
C++ キャスト でぐぐるといいよ
(キャストはCにもあるけど)

361:はちみつ餃子
21/08/25 22:29:05.16 /Q8zinJC.net
>>359
型変換はその名前の通り型を変換する。 変換と同等の処理を普通の関数とし
て書いてもかまわないんだが、変換関数 (conversion function) または変換
コンストラクタ (converting constructor) が定義されていると暗黙の型変換
が適用される文脈では勝手に適用して変換してくれるので便利。
例えば以下のように foo 型のオブジェクトを受けとる文脈で bar 型のオブジェ
クトを渡しても通るのは変換が適用されるから。
struct foo {};
struct bar {
operator foo() {
return foo();
}
};
void func(foo) {}
int main(void) {
foo x = bar();
func(bar());
}

362:デフォルトの名無しさん
21/08/26 01:12:00.54 BlNdGFU0.net
>>361
ようやくイメージできてきました。ありがとうございます!

363:デフォルトの名無しさん
21/08/26 06:25:31.31 C2TXXzWD.net
>>361
そんな難しくせずに、
{ change A to B }
でいいんじゃないの?

364:デフォルトの名無しさん
21/08/26 09:12:40.22 QSgOZ0Rh.net
なんのこっちゃ

365:デフォルトの名無しさん
21/08/27 08:15:52.67 ue9a70Za.net
コマンドライン引数の意味が全く分からないのですが
Visualstudioを使っているからでしょうか?
それとも、コマンドプロンプトの使い方を理解できないでしょうか?
URLリンク(programming.pc-note.net)
ここも参照にしたのですが何が得で何ができてるのかよく分かりません。
コマンドラインってVSでデバッグ無しで実行をした時に出る黒い画面ではないですよね?
質問ばかりですいませんが本当に何も分からないのでお願いします。

366:デフォルトの名無しさん
21/08/27 11:14:47.31 xylLBHc1.net
>>365
メモ帳でファイルをドラッグアンドドロップで開く例が紹介されているが
これはWindowsのShellであるExplorerがexefileに対して登録されているドラッグアンドドロップハンドラーを処理してドロップしたファイルのフルパスを文字列として起動するプロセス環境のコマンドラインパラメータとして渡している
黒い画面(コマンドプロンプト)にもExplorerとは違うがプロセスの起動とパラメータを渡す機能が実装されている
起動するexefileに続けてスペースを開けたあと記入した文字列がそのままパラメータとして渡される
ファイル名以外にも自由に渡せるためプログラムの動作を指定したり変更する目的で使用される
あなたが作成するプログラムでシェルから渡されたコマンドラインパラメータを確認する方法はそのページにもある通りだ
コマンドラインパラメータを活用してバラ色の人生を満喫してくれ

367:デフォルトの名無しさん
21/08/27 14:23:11.73 8dQk5Ix1.net
getopt

368:デフォルトの名無しさん
21/08/27 23:33:15.78 cMIVTei2.net
例えば、デスクトップにショートカットを作る。
コマンドプロンプトを起動して、Ruby スクリプト・a.rb を実行する
リンク先
C:\Windows\System32\cmd@.exe /k "ruby C:/Users/Owner/Documents/a.rb"
注意。書き込めないので、間に@を入れました
作業フォルダ
C:\Users\Owner\Desktop
a.rb 内には、puts ARGV
(ARGV は配列で、そこにコマンドライン引数が渡ってくる)
と書いておいて、ショートカットに、フォルダx・ファイルb.txt をdrag&drop すると、
コマンドプロンプトが起動して、以下のように表示される
C:\Users\Owner\Desktop\x
C:\Users\Owner\Desktop\b.txt

369:デフォルトの名無しさん
21/10/06 22:36:41.57 OG+j1FAK.net
const char* const str[]={"aaa","bbb","ccc"}
constの効果を教えてほしいです
後ろのstrの前のconstは付けると
const str[0]="dddd"って出来なくなるのは分かったのですが
先頭のconstが分かりません

370:デフォルトの名無しさん
21/10/06 22:51:34.11 ItOX1MR6.net
str[0][0]='d';

371:デフォルトの名無しさん
21/10/06 22:53:20.88 OG+j1FAK.net
>>370
なるほど。
ありがとうございます。

372:デフォルトの名無しさん
21/10/09 07:12:25.69 JFpyaThm.net
ロベールC++入門の代入演算子についてなのですが
コピーコンストラクタのときは動的配列をdelete[]しなかったのに
なぜ代入演算子を使うときだけdelete[]するのか分からないので教えて下さい
本にはm_arrayには前に確保したメモリが存在するためdelete[]しないとメモリリーク
と書いてあるのですがコピーコンストラクタも同じじゃないの?と混乱してます
100行目です
URLリンク(ideone.com)

373:デフォルトの名無しさん
21/10/09 10:44:46.48 tDH5FAwQ.net
newしたメモリが不要になったらdeleteする
これだけ
コピーコンストラクタでのdelete、
いつnewしたデータに対して?

374:デフォルトの名無しさん
21/10/09 17:51:02.84 QAOoCtV/.net
>>373
すいません、わからないです。
コピーコンストラクタはnewでアドレスを確保しないものなのですか?

375:はちみつ餃子
21/10/09 18:03:01.95 Z56nk6n1.net
>>374
ロベールの C++ 入門を読んだことがないからどういう構成になっとるか知らんけど、
それがわからんのならたぶんそれ以前の章を理解でてきないと思う。

376:デフォルトの名無しさん
21/10/09 18:04:17.21 jELfb/xT.net
>>372
代入演算子は既にあるオブジェクトを別のオブジェクトで上書きする操作
コピーコンストラクタは別のオブジェクトから新しいオブジェクトを作って初期化する操作
代入演算子でdelete[]しているのは既にあるオブジェクト(*this)のメンバとして確保済みのメモリ領域
コピーコンストラクタの実行時には「既にあるオブジェクト」にあたるものは無いので、deleteするものも無い

377:デフォルトの名無しさん
21/10/09 20:35:07.35 QAOoCtV/.net
>>376
初期化と代入の知識が曖昧でした
分かった気がします。ありがとうございます。

378:デフォルトの名無しさん
21/10/10 20:55:50.73 6QW0WSDe.net
AtCoderの初心者向けのC++の説明のページを読んでいます。
vector<int> a(10);
aの第i番目の要素にアクセスする場合、a[i]よりもa.at(i)と書くほうが良いと書いてあります。
これは現在のC++で推奨されている書き方でしょうか?それとも単に初心者はそう書いたほうがいいというだけのことでしょうか?

379:ハノン
21/10/10 21:05:41.56 KKHdhYPj.net
>>378
>a[i]よりもa.at(i)と書くほうが良い
そう主張されている理由はどのように書かれていますか?私はどちらでも大差ないと思っていますが‥‥

380:デフォルトの名無しさん
21/10/10 21:07:18.12 6QW0WSDe.net
>>379
vector<int> a(10);
b = a.at(10);
などと書いた場合にコンパイルエラーになりますが、エラーメッセージがatを使うと表示されるというのが理由です。

381:デフォルトの名無しさん
21/10/10 21:08:35.36 6QW0WSDe.net
初心者でないプログラマーでatを使って書いている人は少数派ではないのですか?

382:デフォルトの名無しさん
21/10/10 21:31:47.25 zWyM5YPA.net
範囲外にアクセスする可能性があるならat、ちゃんと事前にチェックするなら[]でいいんじゃない?

383:デフォルトの名無しさん
21/10/10 22:58:42.68 gnqjARRQ.net
気分によるけどatが好きです

384:デフォルトの名無しさん
21/10/10 23:07:44.84 gmqGyDAJ.net
vector配列を指すポインタを使ってる時に[i]で指定する書き方がよく分からないのでat(i)使ってる

385:デフォルトの名無しさん
21/10/10 23:14:51.45 U88jNIFg.net
(*ポインタ)[i]

386:はちみつ餃子
21/10/10 23:15:56.24 cCUvKLuJ.net
>>378
これのことだね。
URLリンク(atcoder.jp)
例外処理やアサートの説明を省略しているせいでどう使い分けるべきものなのかがよくわからん説明になってる。
C++ はかなり複雑で、 AtCoder のサイトにある雑な説明だけでは細かいところまで理解はできないよ。
C++ の言語仕様の詳細を理解するのに手間取って競技を始められないくらいならそういう風に割り切れという意味で
AtCoder としては at を推してるんであって、言語仕様やプログラマの習慣としてどちらかを推奨してたりはしない。
それぞれに用途がある。

387:はちみつ餃子
21/10/11 00:50:58.08 kxIK5/L+.net
余談だが C++ の言語仕様としては推奨というのはないが非推奨というのはあって
(結果的に同等のよりよい機能を推奨するのと同じことになっている場合はある)
将来の言語仕様の更新で廃止するつもりがあるということを意味する。

388:デフォルトの名無しさん
21/10/11 02:00:14.70 xizp5ONl.net
ポインタ->operator[](i)

389:デフォルトの名無しさん
21/10/13 01:04:04.91 gvBCET4D.net
Notepad++でcppファイルを選んで実行をすると
Visualstudioが立ち上がるのですが
どうすればNotepadで実行出来るのでしょうか?

390:ハノン
21/10/13 02:24:33.63 YMzdF2UZ.net
>>389
コンパネ→既定のプログラム→ファイルの関連付け

設定→アプリ→既定のアプリ→ファイルの種類ごとに
あたりでなんとかならないでしょうか?

391:デフォルトの名無しさん
21/10/13 03:03:01.45 gvBCET4D.net
>>390
回答ありがとうございます。
ファイルの関連付けをメモ帳とVisualstudioしか選べなかったです。(後Microsoftストア)
Notepad++は初期設定結構大変な感じなんでしょうか?
URLリンク(imgur.com)

392:ハノン
21/10/13 19:41:40.64 YMzdF2UZ.net
>>391
たしかに「設定→アプリ→既定のアプリ→ファイルの種類ごとに」
はうまくいかないですね
では、
開きたい拡張子を持ったファイルを右クリック→プログラムから開く→別のプログラムを開く→その他のアプリ→このPCで別のアプリを探す
ではどうですか?
私は win7 メインで、うまいアドバイスができなくてすみません‥‥

393:デフォルトの名無しさん
21/10/19 08:20:19.87 7/3R28mC.net
C++でアプリを作る場合って、QTってやつかMFCって奴を勉強すればいいのでしょうか?
C++でWIN32APIを学ぶっていうのはないですか?

394:デフォルトの名無しさん
21/10/19 10:04:52.66 emsejTNf.net
ないです

395:デフォルトの名無しさん
21/10/19 10:18:17.44 vPA5f3eX.net
あります

396:デフォルトの名無しさん
21/10/19 11:51:03.31 90qj1F6l.net
メッセージループによるイベントドリブン型アプリケーション
「ウインドウ」と「メッセージ」というウインドウズの基本概念ぐらいは理解してもいい

397:デフォルトの名無しさん
21/10/19 19:00:27.41 C9DkQou5.net
tcl/tk
wxWidgets
DXLib
Unity

398:ハノン
21/10/19 20:20:27.92 KyySFZDA.net
>>393
「C++でwin32api」ですか…
そういうのは c で win32api を理解した後、各自が独力で工夫して c++ と win32api とを辻褄あわせするものだと思っていましたが、それはそうと、そういう書籍は過去にありました
たしか leaf というライブラリと WOOL という lisp 処理系が掲載されていた記憶があります

399:デフォルトの名無しさん
21/10/19 22:23:42.02 P+gkhAFH.net
MFC は何十年も前だけど、今もあるの?
QT は、Linux で聞くけど、Windows で使うの?

400:デフォルトの名無しさん
21/10/20 02:20:42.50 +2OzLQ7p.net
>>399
Qt5Core.dllで検索する色々出てくるから、win/macとマルチのアプリなんかで割と使われてみたいね。
手元だとfusion360とかresolveとかで使われてるっぽい。商用ライセンスあるからかな?

401:デフォルトの名無しさん
21/10/20 11:06:18.19 OEiI06HQ.net
5以前は良かったんだがな

402:はちみつ餃子
21/10/20 13:35:36.40 dLyN/sz8.net
>>393
MFC は API の利用をちょっと楽にする薄いラッパーという感じだな。
API のことを忘れて MFC の使い方だけ学べばよいというようなものではない。
>>398
今は C++/WinRT の時代だぞ。

403:デフォルトの名無しさん
21/10/20 18:01:15.01 oZqSjSwG.net
>>398-402
WIN32やったことないんですが
C++でアプリを作るときはWin32APIは避けては通れないのですか
ありがとうございます…

404:デフォルトの名無しさん
21/10/20 19:03:46.64 CkfuGqw9.net
知っておいた方が良いけど
避ける方法もある

405:デフォルトの名無しさん
21/10/20 19:36:43.86 +2OzLQ7p.net
>>403
いや自分で書いてるQtって奴や>397なら違う世界観を満喫できると思う。
2Dゲーム系ならSDL2あたりも。他にもメンテされてるライブラリあるけどSDL2で引けば出て来ると思う。

406:ハノン
21/10/20 20:15:37.71 I2cv7mAQ.net
>>402
ええ?
WinRT って .NET の世界のものかとおもっていました

407:デフォルトの名無しさん
21/10/20 23:17:39.77 vkb7a42p.net
>>406
C++でも出来るよう

408:はちみつ餃子
21/10/21 00:38:03.74 JAunV20A.net
>>406
WinRT は Windows のモダンな API セットで、特定の言語に結びついたものではない。

409:デフォルトの名無しさん
21/11/05 12:47:56.16 dj6lZ6W1.net
無名クラスのメンバ関数の実装を宣言と別にすることって可能ですか
struct {
int func_hoge(int n);
} myClass;
(実装)?

410:デフォルトの名無しさん
21/11/07 08:51:29.08 +fO8/EKc.net
std::vecotrのインスタンスを作ったとき、指定した要素数以上のメモリを確保しないようにはできますか??

411:デフォルトの名無しさん
21/11/07 11:43:59.55 cdTTDz5e.net
実装依存
普通は出来ない

412:デフォルトの名無しさん
21/11/09 14:46:05.51 t/ZCl1K7.net
普通でなく指定したバイト数以上のメモリを確保しようとしたら例外が上がる実装例
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
#define MAX_SIZE 100
template <class T, class Alloc=allocator<T>>
class SizeLimitedAllocator {
public:
typedef T value_type;
T *allocate(size_t n) {
if (n > MAX_SIZE) throw bad_alloc();
return allocator_traits<Alloc>::allocate(allocator_, n);
}
void deallocate(T *p, size_t n) {
allocator_traits<Alloc>::deallocate(allocator_, p, n);
}
private:
Alloc allocator_;
};
int main()
{
vector<char,SizeLimitedAllocator<char>> vec(MAX_SIZE);
try { vec.resize(MAX_SIZE+1); }
catch (bad_alloc& e) { cerr << e.what() << endl; }
return 0;
}

413:デフォルトの名無しさん
21/11/25 04:15:10.15 0166A/na.net
void *q = (void*)p;
void *r = reinterpert_cast<void *>(p);
void *s = static_cast<void *>(p);
どっちが良い?

414:はちみつ餃子
21/11/25 04:51:08.49 Mn8CZmYm.net
>>413
static_cast で可能なものなら static_cast を使うのが行儀が良い。
Cスタイルのキャスト記法は適用範囲が広すぎて意図通りではない (危険な) 変換でもコンパイルが通るかもしれんということで
複数のキャストを用意しているので意図にあてまる限りなるべく狭い効果を持つキャストを用いるべき。

415:デフォルトの名無しさん
22/02/10 15:34:30.67 Ido/99Jv.net
githubからcshogiというパッケージをインストールしようとしたところ
ビルド中に
src/mate.cpp:110:26: error: template parameter redefines default argument
というエラーが発生しました。
実行コマンドは
CPPFLAGS=-std=c++17 pip install git+URLリンク(github.com)
としているのですが、あれこれ調べてもう打つ手がなくなりそうです。なにが悪いでしょうか。
macOS12.2付属のclangでビルドしています。(他の人は使っているので、文法などは問題ないはずだと思っています。)

416:デフォルトの名無しさん
22/02/10 15:42:07.23 J5PrGMnU.net
そのエラーメッセージで検索すれば?

417:デフォルトの名無しさん
22/02/10 15:46:35.62 Ido/99Jv.net
>>416
とっくにやってますわ!と言うところでしたが、stackoverflowでぴったりなのがありました。
URLリンク(stackoverflow.com)
gccならよさそうですね。

418:デフォルトの名無しさん
22/03/15 20:43:42.96 +mlS0n0o.net
test

419:デフォルトの名無しさん
22/03/15 21:05:11.63 q9dCXwxq.net
Borland C++Builder 1が無料ダウンロードできるようですが
Borland C++ Compiler 5.5 freeとは全く別物でしょうか?

420:デフォルトの名無しさん
22/03/17 11:44:12.82 Y2OAtTnf.net
1は大昔のを記念に無料DL可にしたやつじゃないかな
最新のやつもCommunity Editionていう無料版があるから、開発に使うならそっち
あとBuilderはVisual Studioのような統合開発環境でコンパイラも含まれる

421:デフォルトの名無しさん
22/03/18 12:32:15.10 Fw15ZxLZ.net
ロベール読んでるけど、途中からコードとファイルを端折りすぎてどこに書いてるのか理解出来ない

422:デフォルトの名無しさん
22/03/19 14:31:38.38 T81w77OE.net
>>421
その本(サイト?)はあまり読んでないからわからないけど、こういう知識・技術系は複数の本やサイトを利用したほうがいいかも
基本はそのロベールで、曖昧な部分は他のテキストでみたいに
まあ逆でもいいけど

423:デフォルトの名無しさん
22/03/21 11:12:55.05 Prmlj1K5.net
分割コンパイルの仕組みちゃんと理解しないまま雰囲気でヘッダインクルードしてるんですけど
cppファイルに#pragma once書かないのってどうしてですか??

424:デフォルトの名無しさん
22/03/21 11:22:20.21 S8aTENmp.net
>>423 書いても意味ないから。

425:デフォルトの名無しさん
22/03/21 11:45:05.99 TlR/Mg8q.net
>>423
まあ普通一回使ったら足りるからだけど、
cppをincludeしてたら意味があるのかもな

426:デフォルトの名無しさん
22/04/07 19:54:53.05 ozPVuLqH.net
cppってインクルード出来たんだ
ヘッダーだけかと思った

427:デフォルトの名無しさん
22/04/11 15:54:11.00 LBY7PFnU.net
単にコピペしてくるだけだけだからなんでもいいぞ
ルックアップテーブル計算してテキストにダンプし、ソース中に#include "table.txt" で取り込むのを見たことがある

428:デフォルトの名無しさん
22/04/11 19:50:08.66 uaVZR/I2.net
IDEだと、プロジェクトに.cppを含めるとコンパイル対象になるので.inlとかにしておくのが無難

429:デフォルトの名無しさん
22/04/30 07:28:15.03 2aZ7UOTr.net
前は中身がcppっぽいのはcppにしてたけど
インクルード前提のファイルはhにするようにした
#define ほにゃらら
#include ファイル名.h
##undef ほにゃらら
インクルードしても単体ソースとしても使えるヤツはcpp
ツールが吐き出したコードやデータでそのままincludeして使えるものは拡張子はそのまま

430:デフォルトの名無しさん
22/06/11 20:56:47.72 zBk/MBZO.net
hpp

431:デフォルトの名無しさん
22/06/11 21:01:36.29 N4H8T0pQ.net
h と hpp どっちにするかの話じゃなくて
(h or hpp) にするか
(c or cpp) にするか
の話

432:デフォルトの名無しさん
22/06/11 21:02:37.04 N4H8T0pQ.net
初心者はトリッキーな使い方はしない方が良いから聞かなかった事にして

433:デフォルトの名無しさん
22/06/11 21:20:49.53 kM12Kkyp.net
トリッカーズ。

434:デフォルトの名無しさん
22/06/12 10:33:13.76 cPTHwR7Q.net
三角形の秘密はね

435:デフォルトの名無しさん
22/06/12 11:16:51.08 v0rlTKHd.net
おなかがすいたら

436:デフォルトの名無しさん
22/06/12 19:40:55.19 r44ApDPu.net
ピーナッツ

437:デフォルトの名無しさん
22/06/23 10:13:29.99 06mLNX8U.net
なんか、すごい達者さんが並んでますけど、
ここって、
「プログラミング初めたいけど、なんにもわからないので、初めから教えてください。」
というスレです。

438:デフォルトの名無しさん
22/06/23 10:52:47.91 M4XLJX6g.net
最初からでも0からでも構わんが
自分で努力しないやつはだめ

439:デフォルトの名無しさん
22/06/23 11:07:51.97 XRNmRbRA.net
俺は努力しなくてもできちゃうからなあ

440:デフォルトの名無しさん
22/06/23 14:33:26.79 06mLNX8U.net
掛け算の*と、「何ですか?」の*と一緒なんですが、
区別する方法を教えてください。

441:デフォルトの名無しさん
22/06/23 19:37:03.84 WbbET00J.net
ポインターの事?

442:デフォルトの名無しさん
22/06/23 19:47:14.20 hToQs/iZ.net
は?何ですか?

443:デフォルトの名無しさん
22/06/24 10:44:51.77 K2we1Lar.net
オレオレ

444:デフォルトの名無しさん
22/06/24 12:54:50.02 fYiV2rYB.net
そうだよオレだよ

445:デフォルトの名無しさん
22/07/16 16:13:36.70 2GuJXeRO.net
>>440
掛け算の*は二項演算子
「何ですか?」の*は単項演算子
*の前に項があるかどうかで判断する

446:デフォルトの名無しさん
22/07/16 17:44:38.20 WOPsEo4E.net
数字の、xxxと、
数字の、AAAの掛け算は、
xxx*AAAで、いつも迷うんです・・・

447:デフォルトの名無しさん
22/07/16 18:00:17.69 QRg/sabr.net
*a+++ ++*b
で迷え

448:デフォルトの名無しさん
22/07/16 18:01:53.10 QRg/sabr.net
+*a++*++*b
これも

449:デフォルトの名無しさん
22/08/01 07:12:02.16 yd/7YIgU.net
map よりも unordered_map の方が高速ですか?
あと追加順が保障されないのが unordered_map ですか?
map は何順ですか?

450:デフォルトの名無しさん
22/08/01 13:52:12 jhXgj6wH.net
おまいは何を言っておるのだ?

451:はちみつ餃子
22/08/01 15:12:11.10 YhL9Bhjt.net
>>449
> map よりも unordered_map の方が高速ですか?
操作によるので一概には言えない。
一般的には unordered_map のほうが有利なことが多いとは言えるけれど。
> 追加順が保障されないのが unordered_map ですか?
map でも unordered_map でも追加した順序は保持されない。
C++ に限らず辞書的なデータ構造では格納順序を保持しないのが普通で、
保証があるのは Ruby の Hash くらいだと思う。
Go や Rust だと辿る順序を乱数でかき乱す実装になっているくらいだし。
> map は何順ですか?
キーの順序。
特に指示しなければデフォルトではキーを std::less で比較した順序。

452:デフォルトの名無しさん
22/08/05 04:26:17.70 ECXKpFJi.net
そもそもmapの順序ってなんぞや
そりゃ内部表現としての順序(あるいは非順序という名の実装依存の順序)はあるけど
腹ワタ開腹して弄くり回したら、それはもうmapとは呼べねーよ

453:デフォルトの名無しさん
22/08/16 01:02:16.19 pMrCsY/x.net
vector<int*> xの特定の要素を削除したい場合
delete x[1];
してから
x.erase(x.begin()+1);
という手順であってますか?
deleteしないとメモリリークしますよね?

454:はちみつ餃子
22/08/16 01:10:03.51 +o+ePBjP.net
>>453
それでいいよ。
でもスマートポインタを活用するとかの工夫はしたほうがいいね。

455:デフォルトの名無しさん
22/08/18 11:36:39.99 p/limWqp.net
そもそも移動が大量に発生するのでそんな設計しない

456:デフォルトの名無しさん
22/10/14 20:52:11.42 IQ8pOIWW.net
4ビットだから符号無しなら0~15だろ
コレを-8~7の符号付きにしたいということか?

457:デフォルトの名無しさん
22/10/15 16:23:31.27 B8kXjL18.net
普通に下駄履かせれば(引き算)

458:デフォルトの名無しさん
23/05/24 23:52:31.95 lCJuR93r.net
いやー今日はめっちゃ勉強したわ
詳しくなった

459:デフォルトの名無しさん
23/06/04 09:18:18.28 5jvZ+YKl.net
誘導されて来ますた、
質問なのですがstd::stringに格納された数値文字列を数値にしたい、
しかし数値以外の文字(ただし空白文字は認める)が後ろにくっついていたらエラーにしたい、と言う場合どうす
れば良いの?
ダチャい書き方ならできうるけど人類はいつまでstrtod()や&(str[0])……

460:はちみつ餃子
23/06/04 09:22:50.76 MHoxWKtY.net
>>459
strtod で何が不満なの。
空白かどうかで区別が必要なら空白かどうか確認するしかしょうがないし、
ダサいもくそもないだろ。

461:デフォルトの名無しさん
23/06/04 09:28:48.33 5jvZ+YKl.net
>>460
だって&(str[0])とかナマポやし……
文字列型がchar以外になったら(std::basic_string<TCHAR>とか)になることも見越したら
手でテンプレート書かないといけないから牛刀感があるし、
文字列が厳格に数値文字列なのか検査するとかアプリのコードであるあるなので
アプリレベル(高級アセンブラ的でない書き方)の手段が用意されていて然るべきな気がして仕方が無いし、

462:デフォルトの名無しさん
23/06/04 09:30:18.23 5jvZ+YKl.net
無いというなら仕方が無いが、漏れはちょう初心者ですら……

463:はちみつ餃子
23/06/04 09:37:21.42 MHoxWKtY.net
>>461
std::stod は std::string と std::wstring に対応してるよ。

464:デフォルトの名無しさん
23/06/04 09:39:47.38 5jvZ+YKl.net
>>463
std::stod()は数値への変換が行われなかったとき例外をスローするが
後ろに余計なものが付いていたらスルーするんじゃ……
なお試したことはありま栓、

465:はちみつ餃子
23/06/04 09:52:59.20 MHoxWKtY.net
>>464
???
それで何か困ることがあるという話なの?
要件が不明瞭でよくわからん。

466:デフォルトの名無しさん
23/06/04 09:55:13.77 5jvZ+YKl.net
実は正規表現でも使えば何とかなる……
のか……
std::regex re("^\s*([\d.]+)\s*$");
std::smatch m;
if (std::regex_match(str, m, re)) {
 return m[1].str().strtod();
} else {
 エラー
}

 

467:デフォルトの名無しさん
23/06/04 09:56:15.54 5jvZ+YKl.net
>>465
仕様は最初に提示stkr、
123.456E+8 : OK
123.456E+8a : NG

468:はちみつ餃子
23/06/04 10:00:50.19 MHoxWKtY.net
>>467
続くものが何であるかは自分で確認してエラーにするという話をしてると思ったんやが。

469:デフォルトの名無しさん
23/06/04 10:05:01.33 5jvZ+YKl.net
>>468
>続くものが何であるかは自分で確認してエラーにする
・できればライブラリでやってホスイ
・自分で書くとしてもナマポ(&(str[0]))は避けたい(>>461
・std::string部分が他の文字列型に変わっても大丈夫なサポートがあるならそれに乗っかりたい手でテンプレートを書きたくない(>>461
できるかできないかで言えば、std::stringについてはダチャくあっても実現できてはいるので
C++でちょう簡潔に書ける手段が実はあるのではないか、ありませんか、というのが質問の意図

470:はちみつ餃子
23/06/04 10:13:13.65 MHoxWKtY.net
>>469
続くものの種類で判断するというピンポイントな要求にマッチするものはさすがに標準にあるわけない。
それを除けば std::stod が十分に要求を満たしているように見える。

471:デフォルトの名無しさん
23/06/04 11:40:09.61 bxWaSYac.net
単位でも確認したいの?
だったらstd::ends_withとかstd::rfindとstd::substrで数字の後ろ切り出すとかでチェックしてからstd::stodでよくね
チェックは自分の要件だから自分で書け標準ライブラリはお前のお母さんではない

472:デフォルトの名無しさん
23/06/04 11:51:26.73 xmEQJDCs.net
正規表現でチェックするのが1番自然な気がする

473:デフォルトの名無しさん
23/06/04 22:03:06.86 5jvZ+YKl.net
>>471
> 単位でも確認したいの?
> だったらstd::ends_withとかstd::rfindとstd::substrで数字の後ろ切り出すとかでチェックしてからstd::stodでよくね
std::stringに格納された数値文字列を数値にしたい、
しかし数値以外の文字(ただし空白文字は認める)が後ろにくっついていたらエラーにしたい(>>459
> チェックは自分の要件だから自分で書け標準ライブラリはお前のお母さんではない
チェックのためには(例えばstd::stodが)どこまで読んだのかの情報が要る
std::stodの裏側では文字列を数値解釈する枯れたコードが動いているわけで、
そいつにどこまで読んだのか、ただ1個の整数データを聞けさえすれば良い。
これはそれほど無茶な話ではないはずで実際strtod()ではできるから
どっちかというtライブラリにちょっち不備があるのでは案件であってお母さん案件ではない。

474:デフォルトの名無しさん
23/06/04 22:20:35.13 5jvZ+YKl.net
>>472
上に書いた通り(例えば)std::stodがどこまで読んだのかだけイブラリが返してくれさえしたら解決するのじゃ
正規表現は意味的には合目的的な手段やが、普通の正規表現エンジンの実装なら正規表現オブジェクトを作った際に
FSMを(表形式か何かで)生成する処理が中で動くので、そんなに軽い処理ではないからやっぱ牛刀感みある…
いったん作ったらマッチングは表駆動でやれるので速いことが気体できるのではないか、という香具師が居るかもしれないが、
実はstd::stod()に最大限仕事させたい(正規表現の側で数値文字列の書式についてわざわざ指定したっくない
場合は>>496の正規表現は正しくは "^\\s*(.*?)\s*$"にせねばならないからマッチング時にバックトラックが発生して遅い可能性がある
これもちょっちイヤソな理由
繰り返しになるが(例えば)std::stodがどこまで読んだのかだけイブラリが返してくれさえしたらこんな考慮は不要で完全に円満に解決するのじゃ……

475:デフォルトの名無しさん
23/06/04 22:30:29.50 bxWaSYac.net
>>473
そんな長文ギャンギャン書きなぐってる暇があればstodの仕様くらい調べろよ
ちゃんとお前の欲しがってる物を返してくれるよ

476:デフォルトの名無しさん
23/06/05 00:32:44.63 8dockxGx.net
便乗質問していいですか
某所で似たような問題があったのだけど、付加条件として、数値がINT_MAXを超える場合は
INT_MAX、INT_MINを下回る場合はINT_MINを返す、がありました
stodを使う場合(stoll等でもいいですが)、これってどうやって処理すればいいですかね

477:デフォルトの名無しさん
23/06/05 00:38:04.95 8dockxGx.net
念の為「数値が」というのは元の文字列での、です。たとえば "1000000000000"みたいな
可能性としてはLONG_LONG_MAXを超えている場合もありますね

478:デフォルトの名無しさん
23/06/05 00:46:19.80 oX+QCkCh.net
stoi系は範囲越えたらstd::out_of_rangeを投げるはずだが

479:デフォルトの名無しさん
23/06/05 01:19:48.15 8dockxGx.net
_MAXで超えたか_MINで超えたかってわかりますかね

480:デフォルトの名無しさん
23/06/05 01:31:31.21 oX+QCkCh.net
先頭文字が'-'かどうか見れば?

481:デフォルトの名無しさん
23/06/05 01:54:42.53 yTJt/rkc.net
>>475
どういうこっちゃkwsk、

482:デフォルトの名無しさん
23/06/05 02:04:38.53 LZnxgWkc.net
>>481
URLリンク(ja.cppreference.com)

> pos がヌルポインタでなければ、ポインタ ptr (変換関数の内部的な変数) が str.c_str() 内の最初の変換されなかった文字のアドレスを受け取り、その文字のインデックスが計算されて *pos に格納されます。 これは変換によって処理された文字数になります。

> 引数
> str - 変換する文字列
> pos - 処理された文字数を格納する整数のアドレス

483:デフォルトの名無しさん
23/06/05 02:37:23.50 yTJt/rkc.net
>>482
㌧クスわかりたorz

484:デフォルトの名無しさん
23/06/05 06:49:34.05 8dockxGx.net
>>480
そうですね、でも文字列の先頭とは限らないですよね。やはりこの場合はある程度は
自力で文字列をパースする必要がある感じですかね
ちなみに数字以外が含まれるときの挙動は "hoge 123"みたいに数字より前に非数字
がくるのは駄目だけど逆に"123 hoge"みたいのはおkなんですね

485:デフォルトの名無しさん
23/06/20 19:02:06.99 mbwsU8Mq.net
話題がないから質問してみる
struct Summer {};
Summer summer;
Summer *const summerConstPtr{};
const_cast<Summer*>(summerConstPtr) = &summer; // だめ
const_cast<Summer*&>(summerConstPtr) = &summer; // いける
質問1) 最後のいけるやつのconst_cast<Summer*&>の「&」はどういう意味なんでしょう? 参照のことかいな?
質問2) なんでconst_cast<Summer*>ではだめなのかな?

486:デフォルトの名無しさん
23/06/20 19:05:08.72 mbwsU8Mq.net
なんか変換されたw
∑merでなくて&summerです

487:はちみつ餃子 ◆8X2XSCHEME
23/06/20 20:45:04.07 IIzrqfbq.net
>>485
参照が絡むとややこしくて単純に説明できないんだけど
代入演算子の左側は変更可能な lvalue (modifiable lvalue) であることということになっていて
そのキャストだと prvalue になってしまうから代入できないという結果になる。
たとえば
int x = 1;
x = 2;
は有りだけど
1 = 2;
は駄目なのはわかるでしょ。
この代入のときの x はそこに入っている 1 という値に意味はなくて場所に意味がある。
値として取り出されてしまうと代入できないんだ。

488:はちみつ餃子 ◆8X2XSCHEME
23/06/20 20:54:10.99 IIzrqfbq.net
どういうときにどういう値カテゴリに属すことになるのか正確なところはここ見て。
URLリンク(timsong-cpp.github.io)
C++03 時代は lvalue と rvalue だけの単純な (と言ってもそれなりに複雑だが……) 世界だったんだけど
右辺値参照の概念を整理するため (?) かだいぶんごちゃついてる。

489:デフォルトの名無しさん
23/06/20 23:48:13.65 mbwsU8Mq.net
>>487
返答ありがとう。
なぜconst_cast<Summer*>(summerConstPtr)が左辺としていけないのかがわかりませぬ。
summerConstPtrはconst_cast<Summer*>によって「Summer *const」から「const」が外れて「Summer*」となって
Summer *summerPtr;
summerPtr = &summer;
とするときの左辺summerPtrと同じようになったわけではないのでしょうか?
どうもこの左辺summerPtrと同じようにするためには、const_cast<Summer*&>としなければならないようだが、この「&」にはどんな意味ががが??

490:はちみつ餃子 ◆8X2XSCHEME
23/06/21 00:33:00.36 3HBFHOpK.net
>>489
型とは別に (型と無関係ではないが) 文脈にカテゴリが存在するというのが肝心な部分。
どれがどのカテゴリに属すのかはダラダラとした箇条書きで書いてあって単純な原則では示せない。
(結果的には辻褄の合うようになってるけど……。)
& は参照を表す記号という解釈は正しい。
参照は lvalue なのでキャストの結果も lvalue ってだけ。

491:デフォルトの名無しさん
23/06/21 01:03:31.08 tILY3YM/.net
>>489
その理解だと↓も通ることになると思うんだけど、これが通らない理由もわからない?
int i = 0;
static_cast<int>(i) = 1;

492:デフォルトの名無しさん
23/06/21 11:05:32.10 cZp0PZIW.net
>>490,491
「&」はやはり参照でしたか。
左辺の規則と右辺の規則があり、キャストしたポインターでは左辺の規則に従ってなくて、キャストした参照なら左辺の規則に従っていると、そうなっていると覚えるほかないのでありますな。
ありがとう。

493:デフォルトの名無しさん
23/06/29 00:53:29.69 l197jz/x.net
なんで可変長配列の名前がvectorなの?

494:はちみつ餃子 ◆8X2XSCHEME
23/06/29 08:14:12.68 l+ZsGqGg.net
伝統。

495:デフォルトの名無しさん
23/06/29 13:14:41.30 DfwcYShQ.net
URLリンク(www.google.co.jp)
向きを持つ量をベクトルという
向きを持つためには複数の量が必要(単一の量はスカラーという)
それを抽象化して、要素を一列に並べたものをベクトルという

496:デフォルトの名無しさん
23/07/04 17:43:58.34 Ld2RSFGK.net
c++に限定される疑問ではないかも知れませんが標準出力がどうやってコンソールに出力しているか?というところで躓いてます
gnuのlibcを見てもわからず、アセンブラを見て0x80というシステムコールをしているところまで辿り着いたけど無学なので理解できずにいます
OSが用意している機能を実行しているという認識であってますか?

497:はちみつ餃子 ◆8X2XSCHEME
23/07/04 17:52:47.39 wwaI/oJF.net
>>496
そうだよ。
現代の OS は権限の管理がしっかりしてて、アプリケーションは
プロセスの外のリソース (メモリやデバイス) を直接には使えない。
OS に要求して適当なところに橋渡ししてもらう構造。

498:デフォルトの名無しさん
23/07/04 18:05:29.71 Ld2RSFGK.net
>>497
どうやって実行中のコンソールに出力しているのだろうという素朴な疑問だったのですが、この先はOS仕事という事なんですね
自分で見ろって言われるかもしれませんが、OSの処理の実装を見るのは難易度高いですか?
HelloWorldからどちらに進もうか迷ってます

499:デフォルトの名無しさん
23/07/04 19:16:32.21 Ld2RSFGK.net
同様のテーマのITmediaの記事を見つけたので腰を据えて取り組んでみようと思います
回答いただきありがとうございましたお騒がせしました

500:はちみつ餃子 ◆8X2XSCHEME
23/07/05 00:40:03.93 h//lr2GB.net
>>498
標準出力の実態はパイプ。
パイプの接続先がターミナルのプロセスが繋がってるだけでカーネルはそれほど大したことはやってない。
と言えれば簡単なんだけど端末制御まわりは歴史的事情でよくわからんことになってるので
ソースコードだけから読み取ろうとするのはしんどいと思う。

501:デフォルトの名無しさん
23/07/13 01:46:39.34 a7xsv8mg.net
shared_ptrの解放時にweak_ptrを登録していたSTLコンテナから登録抹消したいけど、
shared_ptrのデリータでshared_ptr自身は扱えないっぽい。
出来ないということは、何か他にいい方法があるか、根本的に何か考え方間違ってる?

502:はちみつ餃子 ◆8X2XSCHEME
23/07/13 18:07:22.25 46c6OBqO.net
>>501
設計意図次第だけど
コンテナにはオブジェクト本体をいれて shared_ptr は
コンテナ内の要素を指すイテレータを指す
という構造はどうだろう。
#include <iostream>
#include <memory>
#include <set>
int main(void) {
std::set<int> container;
auto [iter, result] = container.emplace(42);
{
// コンテナ内の要素を指す shared_ptr をいくつも作る
auto x = std::shared_ptr<decltype(iter)>(new decltype(container)::iterator(iter), [&container](decltype(container)::iterator* p) { container.erase(*p); delete p;});
auto y = x;
auto z = x;
// コンテナの中には要素が入ってる
for (auto& x : container) std::cout << x << " ";
std::cout << std::endl;
// shared_ptr はここで消滅
}
// デリータが消したのでもう残ってない
for (auto& x : container) std::cout << x << std::endl;
}

503:デフォルトの名無しさん
23/07/13 21:30:08.90 BEK5Ztwm.net
>>502 ありがとうございます。実体とイテレータ、参考になります。
おかげで解放時何とかshared_ptrで引数を渡そうとしてましたが、諦めて実体でもいいんではと思い始めました。
回答を見るまでは、shared_ptr<shared_ptr<X>>なら解放時にshared_ptr<X>取れるじゃん、
修正とか色々めんどくさいけど、とかアホなこと考えてました。

処理の概略はshared_ptr側で値管理、コンテナ側は登録されたweak_ptrの値と別の値が合致したら処理、
shared_ptr側解放時コンテナ側から登録抹消(抹消関数の引数にshared_ptr:これがNG)というものです。

504:デフォルトの名無しさん
23/07/16 13:37:45.84 aonKa36p.net
設計意図次第

505:504
23/07/16 21:29:25.31 AcIm+utR.net
何でかshared_ptrって派生出来ないと思い込んでたけど出来た。
shared_ptrで出来ない理由は分からんが、他に変な問題が無ければほぼ当初の想定通り。
ありがとうありがとう。

template<class T>
struct X : public std::shared_ptr<T> {
X(T* t) : std::shared_ptr<T>(t){}
~X(){/*X自体の登録抹消*/}
};

506:蟻人間 ◆T6xkBnTXz7B0
23/07/16 22:10:43.92 /+p/BpGt.net
クラス内部で
using std::shared_ptr<T>;
を付けるとコンストラクタの実装が完璧になるよ。

507:蟻人間 ◆T6xkBnTXz7B0
23/07/16 22:12:03.59 /+p/BpGt.net
>>506
クラス内部で
using std::shared_ptr<T>::shared_ptr;
を付けるとコンストラクタの実装が完璧になるよ。

508:504
23/07/16 22:37:21.87 AcIm+utR.net
>>507 基底クラス(shared_ptr)のコンストラクタを派生側に引っ張って来る便利な奴ですね(覚えきれてない)。
ありがとうございます。自前実装不要なのは助かります。

509:はちみつ餃子 ◆8X2XSCHEME
23/07/17 00:18:57.61 YifLUjyU.net
>>505
それって本当に意図通り?
X のデストラクタが起動するのは X 型のオブジェクトが解体されるときであって
参照カウントがゼロになったときじゃないんだよ。

510:504
23/07/17 01:33:58.67 9b8iHtwy.net
>>509 …あー。それは意図通りではないですね。実際の解放はデストラクタで
use_count()==1であることを確認する必要があるのかな。ありがとうございます。

511:はちみつ餃子 ◆8X2XSCHEME
23/07/18 09:19:59.88 //OyAtPF.net
パブリック継承した型では基底への型変換を禁じることができない。
つまり
X<int> foo = new int(1);
std::shared_ptr<int> bar = foo;
みたいなことが出来てしまう。

間違った使い方を想定するとキリがないから
なんでもかんでもガチガチに型を設計する必要はないんだけど、
この場合はどこかでミスりそうと思うので
私なら継承でスマートポインタの挙動をカスタマイズしようとはしないと思う。

512:504
23/07/19 03:16:45.39 0uGQJSD8.net
>>511
御忠告ありがとうございます。
高々shared_ptr自身を解放するだけと思っていたんですが、色々難しいですね。
> パブリック継承した型では基底への型変換を禁じることができない。
そんな問題があるとは。
派生クラスのキャスト演算子は引っかからず、基底クラスの
コピーコンストラクタをいじらないと禁止出来ないっぽかった。
protected継承にしてみたら代入は出来なかった。うーん、他に問題が無ければこれですかね。
> 間違った使い方を想定するとキリがないから
> なんでもかんでもガチガチに型を設計する必要はないんだけど、
> この場合はどこかでミスりそうと思うので
> 私なら継承でスマートポインタの挙動をカスタマイズしようとはしないと思う。
候補はprotected継承(暫定)、shared_ptr相当自作、或いは他の未知なる何か。
しかし一番素直で的確に機能を実現可能と思っているのがshared_ptrの拡張なので、
別の形で実現する方法はどうも迂遠過ぎて自分には思いつかないです。
# shared_ptr側がデータ実体と登録したコンテナの情報を持ち、コンテナ側はweak_ptrで参照
なので流石に自作は無し、とりあえず他に致命的な問題が無ければprotected継承で実装して、
他により良い方法を思いついたらそっちに乗り換えることにします。

513:504
23/07/19 18:45:15.41 4lyHW67x.net
そういえばweak_ptr試してない…?と思って試したら当然の如く代入できなかったので、
public継承でほったらかします。

514:デフォルトの名無しさん
23/07/20 15:28:07.42 6BSTmMYa.net
templateの世界へようこそ

515:はちみつ餃子 ◆8X2XSCHEME
23/07/21 13:23:19.14 NiBubQrd.net
std::unique_ptr なら型引数でもデリータを与えることが出来て、
型引数が異なれば異なる型ということになる。
#include <memory>
template<class T> struct custom_delete : public default_delete<T> {};
int main(void) {
std::unique_ptr<int, custom_delete<int>> foo{new int(42)};
// ↓ 別の型なので移動できない。 エラーになる。
std::unique_ptr<int> bar = std::move(foo);
}
ところが std::shared_ptr では型引数でデリータをカスタマイズすることが出来ない。
解体は動的な型に従うという保証をしているので。
#include <memory>
struct foo {};
struct bar : public foo {};
int main(void) {
// 解体のときに foo ではなく bar の
// デストラクタが呼ばれることが保証される
std::shared_ptr<foo> x{new bar};
}
std::shared_ptr は動的な情報 (実行時の情報) を元に挙動が決まるというのが
設計理念なので削除方法をカスタマイズしたいならコンストラクタにデリータを渡す
というのが最も自然な形と言える。
std::shared_ptr を継承する形でカスタマイズしようとするのは
してもそれ自体は仕様に反しないけれど不自然だなぁとは思う。 (個人の感想です。)

516:504
23/07/21 20:08:15.21 jaEOXewl.net
一応発端の動かなかったコードを短くしたのでおいときます。
0.動機:shared_ptr<int>のdeleterでvector<weak_ptr>を削除したい
1.deleter内だとxは有効でuse_count 0だったけど、vectorのweak_ptrは無効だったのでvectorから削除できない。
2.shared_ptr<int>のデリータはint*に対するもので、shared_ptr<int>へのポインタはshared_ptr<int>の
デストラクタじゃないと処理できないけど、既製品だから外からいじられない。
3.んじゃ、手っ取り早くshared_ptr継承してデストラクタを使えるようにすれば?
というのが趣旨でした。

#include<vector>
#include<memory>
int main(){
std::vector<std::weak_ptr<int>> v;
std::shared_ptr<int> x(new int(3), [&x, &v](int* i){
for(int j = 0; j < v.size(); j++){
std::shared_ptr<int> t = v[j].lock();
if(t && t == x){v.erase(v.begin() + j); break;}
}
delete i;
});
v.push_back(x);
}

517:デフォルトの名無しさん
23/07/25 09:24:45.92 k8WJtY+U.net
>shared_ptr<int>へのポインタはshared_ptr<int>のデストラクタじゃないと処理できない

これが無理っしょ

518:デフォルトの名無しさん
23/07/28 10:56:39.59 Zgvcm9f5.net
なんで出来ると思ったの

519:デフォルトの名無しさん
23/07/29 20:15:59.76 ETnyq2kJ.net
shared_ptrのデリータで他所様のオブジェクトもついでに解体したろっていう発想そのものが危険な香りしかしなくてゾワゾワする

520:デフォルトの名無しさん
23/07/29 20:25:36.66 xEb8mTKO.net
シャー専用ptr

521:1
23/09/03 20:55:45.58 /ExZEMtW.net
「プログラム」作るのって、やってみたいけど、全然知らないから、教えて欲しい。
からのスレの目的で建てました。

522:デフォルトの名無しさん
23/09/03 20:59:12.95 W287fTtw.net
まず、何が作りたいかイメージしてみましょう

523:デフォルトの名無しさん
23/09/04 10:11:49.98 /ASAZOX6.net
>>521 がC++をやるのは早過ぎる
先にpythonでもやってみろ

524:デフォルトの名無しさん
23/10/02 22:07:14.88 l4Vvzubd.net
次のプログラムを実行するとコメントのように出力がされ、mainの最後で例外が発生してしまいます。
なぜ例外が発生するかわかる方教えてください。
mainを通してnewは2回実行され、deleteも2回実行されるので空ポインタをdeleteしていることもないと思うのです。
#include <iostream>
using namespace std;
class Csmp1 {
private:
int x;
int* p;
public:
Csmp1(int n);
~Csmp1();
void disp() { cout << "x=" << x << endl;}
};
Csmp1::Csmp1(int n) {
x = n;
p = new int;
cout << "constructor " << x << endl;
}
Csmp1::~Csmp1() {
delete p;
cout << "destructor " << x << endl;
}
int main()
{
Csmp1 d3(300); // "constructor 300"と出力
d3.disp(); // "x=300"と出力
d3 = Csmp1(400); // "constructor 400"と出力し、その後"destructor 400"と出力
d3.disp(); // x=400と出力
return 0;
} // デストラクタが呼ばれ、delete の部分で"Unknowin signal"例外発生

525:蟻人間 ◆T6xkBnTXz7B0
23/10/02 22:12:06.36 /sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

526:蟻人間 ◆T6xkBnTXz7B0
23/10/02 22:12:09.92 /sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

527:蟻人間 ◆T6xkBnTXz7B0
23/10/02 22:12:23.61 /sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

528:蟻人間 ◆T6xkBnTXz7B0
23/10/02 22:12:42.13 /sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

529:蟻人間 ◆T6xkBnTXz7B0
23/10/02 22:18:32.15 /sjCb2h4.net
連投すみません。コピーコンストラクタと、代入もです。

530:はちみつ餃子 ◆8X2XSCHEME
23/10/03 00:13:21.44 OUiDjLFt.net
>>524
暗黙に生成される代入演算子は全てのサブオブジェクトを代入したような挙動になるルール。

ポインタを代入した場合には代入元と代入先のポインタが指す先のオブジェクトは同一なので
一方のポインタを通じて delete したならもう一方のポインタからオブジェクトに触れようとしてはならない。
(もう存在しないので。)

この場合は
d3 = Csmp1(400);
としたときに生成される一時オブジェクトはこの式が終わった時点で解体されるので
d3 内にあるポインタはデストラクタで delete 済み、すなわち無効なポインタとなる。
d3 のデストラクタが起動したときはデータメンバ p が指している先は無効なので
無効なポインタをいじったことになって問題が生じる。

それと d3 のコンストラクトのときに new したオブジェクトはどこからも delete されてない。

531:527
23/10/03 00:55:04.57 RKQFDOr6.net
>>529-530
お二人さま ありがとうございます。

>d3 = Csmp1(400);としたときに生成される一時オブジェクトはこの式が終わった時点で解体される

右辺により生成されるオブジェクトが単にd3に格納されるのではないのですか。
それと入れ替わりに、d3コンストラクト時のオブジェクトのデストラクタが呼ばれると思ってました。
(どこからも参照されなくなるので)

自分が根本的に誤っている気がします、すみませんが上の内容でおかしい点を教えてください。

532:はちみつ餃子 ◆8X2XSCHEME
23/10/03 02:13:14.63 OUiDjLFt.net
>>531
> 右辺により生成されるオブジェクトが単にd3に格納

JavaScript とか Python の動的型言語の経験があるのかな?
それとも Java や C# の参照型のモデルで考えてる?

C++ では左辺はメモリ上の特定の場所に対応づいていて、
別の場所 (右辺で生成される一時オブジェクト) にあるものを格納するというのは
コピーするということ。

その上で不要になった一時オブジェクトは解体される。
一時オブジェクトは一部の例外を除いて完結式 (完全式ということもある) の終わりのタイミングで
解体されるルールなのでこの場合は行の終わりが解体のタイミングということになる。

533:はちみつ餃子 ◆8X2XSCHEME
23/10/03 02:13:25.78 OUiDjLFt.net
>>531
> 右辺により生成されるオブジェクトが単にd3に格納

JavaScript とか Python の動的型言語の経験があるのかな?
それとも Java や C# の参照型のモデルで考えてる?

C++ では左辺はメモリ上の特定の場所に対応づいていて、
別の場所 (右辺で生成される一時オブジェクト) にあるものを格納するというのは
コピーするということ。

その上で不要になった一時オブジェクトは解体される。
一時オブジェクトは一部の例外を除いて完結式 (完全式ということもある) の終わりのタイミングで
解体されるルールなのでこの場合は行の終わりが解体のタイミングということになる。

534:はちみつ餃子 ◆8X2XSCHEME
23/10/03 02:17:47.16 OUiDjLFt.net
サーバから書込みエラーが返ってきたのを専ブラの機能でリトライしたら多重投稿になってしまってるな。
なんか不安定な状況っぽい

535:デフォルトの名無しさん
23/10/05 17:15:14.18 WXXGTjkD.net
みんなでリトライするからF5攻撃並みに自爆DOS攻撃

536:デフォルトの名無しさん
23/10/05 18:29:28.73 S7K0dlIY.net
>>524
int *をunique_ptr <int>にすると
コンパイルで弾かれるから
気づきやすいかもね
newとdeleteは直で呼ばない方が良い

537:デフォルトの名無しさん
23/10/06 10:09:01.67 Zl0hPCVy.net
newとdeleteを直で呼んでるかどうかと
今回の問題(コピーが発生してるかどうか)は
関係無いんじゃね?

538:デフォルトの名無しさん
23/10/06 10:16:23.02 QFTcWZUD.net
いきなりC++から入るとは…
考え直した方がいい

539:デフォルトの名無しさん
23/10/06 12:08:09.60 xj8n2YWF.net
>>537
「コピーが発生してるかどうか」とは関係ないのはその通り
>>524が恐ろしいのは
コンパイル時点では気づかず実行して初めて明らかになるところ
どうしたら実行前に避けるかの方策として
unique_ptrの常用を提案しました

540:デフォルトの名無しさん
23/10/06 13:16:53.99 Zl0hPCVy.net
>>524 に有効な解決策は
コピーコンストラクタじゃなくて
ムーブコンストラクタじゃないのかな

541:はちみつ餃子 ◆8X2XSCHEME
23/10/06 16:48:00.89 R7EjAYTn.net
両方やっとけばええじゃろ。

542:デフォルトの名無しさん
23/10/06 21:05:50.93 BgvqARb2.net
vector dp(N+1,vector(i+1,vector<mint>(i,0)));
これはdp[N+1][i+1][i]個のデータを確保していると思っておk?

543:デフォルトの名無しさん
23/10/06 21:10:07.75 G9Jlm58L.net
OK牧場!

544:デフォルトの名無しさん
23/10/06 21:44:11.09 BgvqARb2.net
TXH!

545:527
23/10/16 23:49:47.91 6sfjI2pS.net
>>532 を始めとして皆さんまたまたありがとうございます。
アセンブラ、Cを長くやってきたあと、最近C#を少し覚えたのでそちらと混同していました。

コピーコンストラクタと代入の演算子関数を作ろうとしていますがまだ途中。少しずつ進めます。

546:デフォルトの名無しさん
23/10/17 23:09:31.94 cH9YbrYr.net
既製品のクラスライブラリについて、クラス階層が深いところのクラスは、公開メンバの全体をひと目で見渡すことができません。
マニュアルや継承のツリーををたどって地道に調べるしかないのですか。

547:はちみつ餃子 ◆8X2XSCHEME
23/10/18 09:51:20.64 UZlHr99J.net
>>546
ソースコードの構造を調べるのを補助するツールはあるが
どういう意図でどういう使い方を想定してそう書かれているのかは
プログラマが読み解かないとどうしようもない。

548:デフォルトの名無しさん
23/10/18 17:06:40.02 d+gN3jrr.net
既製品ならドキュメントあるだろ
ドキュメントで謳ってないことはやるべきでない

549:デフォルトの名無しさん
23/10/18 21:01:33.56 XEk7oAP2.net
visual studio community 2022で、
他のソリューションで作成されたmoduleをimportする方法がわかりません。
#includeみたいにパスを指定する方法とかがあるんでしょうか?

550:デフォルトの名無しさん
23/10/18 21:18:35.91 GW9b62tt.net
あるよ

551:デフォルトの名無しさん
23/10/18 22:46:30.83 XEk7oAP2.net
>>550
ぜひ教えてください!

552:デフォルトの名無しさん
23/10/19 10:07:14.52 W1XtHktx.net
外部モジュール取り込みは言語仕様じゃ無くてIDEの機能だから

553:デフォルトの名無しさん
23/10/20 09:56:30.99 /M3RKJCH.net
IDEに頼ってるとアホになるよ

554:デフォルトの名無しさん
23/10/21 16:32:35.29 dhBJRkMq.net
0のうちにやめとけ
時間がもったいない

555:デフォルトの名無しさん
23/10/26 23:16:10.15 4gABazLN.net
typedef uint8_t byte;
:
byte a = 3;
uint8_t b = a;
bの初期化は型不一致エラーにならないと思います。
コンパイラは型の異なる変数の初期化や代入を見つけると、typedefを探して元の型が同一かを調べてエラーにするかどうかを決めるのですか。

556:デフォルトの名無しさん
23/10/26 23:23:19.82 oN20rU1J.net
>>555
typedef は型の別名を作る機能であって新しい型を作らない。

557:デフォルトの名無しさん
23/11/05 12:44:18.01 iVzKXsmj.net
Visual StudioでソリューションAでビルドしたブツ(.exe、.dll、lib)、シンボルファイル(.pdb)、必要なヘッダファイル(.h)
をソリューションBで取り込むの場合、Aのビルド後イベントとBのビルド前イベントを駆使してフォルダのパスは
"$(Solution)..\x\$(Platform)\$(Configuration)" みたいなマクロで解決、みたいなローテク頼みという印象、
Visual Studio 2019以降だと今は実はもっと簡単?

558:デフォルトの名無しさん
23/11/10 23:40:20.59 mtEH7OmF.net
class MyClass {
public:
MyClass();
:
};
int main()
{
MyClass* c = new MyClass(); ①
MyClass d;
MyClass* dp = &d; ②
:
}
オブジェクトのポインタは①や②のように取得できると思います。
私からすると①はdeleteしなければならないのでできれば使いたくない。
①の書き方は、よく入門書に出てくる、継承関係にあるポインタの相互代入のためにあると考えて正しいですか。

559:デフォルトの名無しさん
23/11/10 23:49:08.54 VDRR6isO.net
>>558
その「相互代入」って何ですか?

560:はちみつ餃子
23/11/10 23:56:43.46 Irnop6+y.net
>>558
自動変数の寿命はスコープ単位だから
それより長い寿命のオブジェクトが必要なら new する。
寿命の種類のことを Storage duration といい、
new で生成したオブジェクトは Dynamic storage duration に該当する。
継承関係がどうこうというのは何が言いたいのかよくわからないが、
ポインタの性質はオブジェクトの寿命とは関係ない。

561:デフォルトの名無しさん
23/11/12 00:13:49.90 M40i1rJ9.net
相互代入は言葉がおかしいですね。
基底クラスのポインタで派生クラスのオブジェクトをポイントできるというものです。
オブジェクトのボインタを使う場面があまりないので用途を聞きました。

>>560
>自動変数の寿命はスコープ単位だから
それより長い寿命のオブジェクトが必要なら new する。

自分の場合、関数内より長い寿命が必要となったらそれはもうグローバルにしてしまいます。設計方針がよくないですかね。

562:はちみつ餃子
23/11/12 02:00:51.06 O0gb6uIB.net
>>561
グローバル変数として書いたオブジェクトの寿命は static storage duration に該当する。
この static というやつは main が始まる前に構築されて main が終わった後に解体されるので
必要以上に長い寿命になってしまうことが多いし、
実行時の情報を元にして構築するオブジェクトを static にはしようがない。
dynamic (new でのオブジェクト生成) が必要になる場面はごく普通にある。
ごく普通にあるのに使わずに済ませてるならたぶん不自然な設計になってると思う。
グローバル変数は寿命も長すぎるがスコープも広すぎる。
人間は自分が思ってるより馬鹿だから最初にどういう想定をしてたのか忘れて要らんことをしてワヤにする。
触らせたくないものは隠しておくのはカプセル化の考え方の重要な部分。
本当に人間は忘れるし間違える。
部品ごとに間違った使い方を出来ないように配慮しておかないと規模を大きく出来ない。
まあ逆に言えば小さいプログラムではそんなに凝ったことをしなくても大丈夫なんだけど。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch