0からの、超初心者C++相談室at TECH
0からの、超初心者C++相談室 - 暇つぶし2ch451:はちみつ餃子
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 でのオブジェクト生成) が必要になる場面はごく普通にある。
ごく普通にあるのに使わずに済ませてるならたぶん不自然な設計になってると思う。
グローバル変数は寿命も長すぎるがスコープも広すぎる。
人間は自分が思ってるより馬鹿だから最初にどういう想定をしてたのか忘れて要らんことをしてワヤにする。
触らせたくないものは隠しておくのはカプセル化の考え方の重要な部分。
本当に人間は忘れるし間違える。
部品ごとに間違った使い方を出来ないように配慮しておかないと規模を大きく出来ない。
まあ逆に言えば小さいプログラムではそんなに凝ったことをしなくても大丈夫なんだけど。

563:デフォルトの名無しさん
23/11/12 11:04:18.35 l8rhUXJt.net
>>558
>①の書き方は、よく入門書に出てくる、継承関係にあるポインタの相互代入のためにあると考えて正しいですか。
そのためだけにあるという訳ではない
>私からすると①はdeleteしなければならないのでできれば使いたくない。
生のポインタではなくスマートポインタ(unique_ptrやshared_ptr)を使えば
deleteはスマートポインタがやってくれる
構築は uniqu_ptr <MyClass> = new MyClass(); や
uniqu_ptr <MyClass> = make_unique <MyClass> (); のようにやる

564:デフォルトの名無しさん
23/11/12 13:14:04.39 xpiKETrj.net
> 基底クラスのポインタで派生クラスのオブジェクトをポイントできるというものです。
> オブジェクトのボインタを使う場面があまりないので用途を聞きました。
アップキャストのことだろうかね。
必ずといっていいほど使う機会がある。関数の引数にオブジェクトを渡すときとか

565:デフォルトの名無しさん
23/11/13 06:27:48.00 qbVz2ceg.net
>>558 は、最初から必要数が決まっているオブジェクトしか作ったことがないのかな。
リストやツリー構造を自作していれば、①が必要なケースは分かると思うけど。

566:デフォルトの名無しさん
23/11/13 10:31:45.02 IRswNIWu.net
>>564
型チェックしなきゃ危険だけどな

567:デフォルトの名無しさん
23/11/13 13:26:36.10 qAieNn1D.net
uniqu_ptr

568:デフォルトの名無しさん
23/11/13 18:54:22.80 CCXWxw1E.net
>>567
おおスマン
typoだね

569:デフォルトの名無しさん
23/11/13 23:59:54.01 RLYu3oMv.net
>>562 ほか皆さんありがとう。

自分の関わってきた分野が小規模組み込みだからか、そもそもCでmallocの使用経験がないのです。
処理系がmallocをサポートしないMCUもありました(使いたいなら自分で作ってという思想、標準入出力も)。
なので>>565 さんの指摘は当たりです。

c++に挑戦している今の環境も小規模なので、newの利用はほどほどに検討してみます。

570:デフォルトの名無しさん
23/11/14 00:03:40.68 F1cdKor4.net
>>564
だいたい参照で済んでしまいます

571:デフォルトの名無しさん
23/11/14 12:46:18.30 SRCspH78.net
mallocもnewも使ったこと無いってやばいぞ

572:はちみつ餃子 ◆8X2XSCHEME
23/11/14 15:58:08.40 oTbgWDDI.net
new 演算子はオーバーロードも出来て、型ごとにメモリの確保の仕方を変えるといったようなことも出来る。
メモリの確保と値の構築を別のレイヤとして定義できるということに意味がある。 (いわゆる関心の分離?)
低レイヤでも便利な場面はたぶんある。

分離する甲斐がないほど小規模ならべた書きが悪いわけじゃないけど
あえてべた書きという設計を選ぶってのとなんもわからんで使わないってのでは違う。
知っておくに越したことはないよ。

573:デフォルトの名無しさん
23/11/14 21:59:36.46 WxE96Zj2.net
空配列を用意してそれを順繰り使い回す
チープなCPUでは必須の方法

574:デフォルトの名無しさん
23/11/14 22:15:51.21 VpxEmvp/.net
RAM2KBでmallocが必要かどうか

575:デフォルトの名無しさん
23/11/15 09:06:17.34 vh+zgKB1.net
よく
 A a = new A();
 a->b();
 delete a;
みたいに生成してすぐ解放ってのがありますけど、
 A a;
 a.b();
じゃ駄目なんでしょうか。前者に何のメリットがあるんでしょうか。

576:デフォルトの名無しさん
23/11/15 09:39:21.05 88mXe6hW.net
後者はスタックを消費するから A が巨大なオブジェクトだったら困るとかかな

577:デフォルトの名無しさん
23/11/15 09:40:08.83 7t1hSBTd.net
>>575
A *a = new A(); よね、一応
bを呼び出したいだけなら特にメリットはないよ

578:デフォルトの名無しさん
23/11/15 10:25:46.06 2QF9cM/v.net
スタック?
そんな所にゃ領域取らないだろ

579:デフォルトの名無しさん
23/11/15 16:06:06.00 rnHf5KLb.net
何したらここの人らみたいにプログラム詳しくなれるの?PC98からやらなきゃダメ?

580:はちみつ餃子 ◆8X2XSCHEME
23/11/15 16:35:01.46 k729Xl/N.net
>>575
> ありますけど、

ないよ……。
少なくともそう頻繁にはない。

あるとしたら >>576 が指摘するように A が特に巨大な場合というのはひとつの可能性。
ただ、巨大になるのがわかってるならリソースを分割して A の中で
上手いことやりくりする (A 自体の大きさは抑える) べきで、
クラスを使う側で配慮しなきゃならないのは普通は悪い設計だと思う。

第二の可能性として、 new 演算子をオーバーロードして
そのオブジェクトがメモリの特定の場所に対応づけられる場合。
メモリバス経由でデバイスと接続するようなアーキテクチャもまあまあ有るから
それを C++ 上ではオブジェクトのように抽象化するということはあるかもしれない。
でもそれは低いレイヤだけの話で、
適当にラップするクラスを作ってもうちょっと抽象度の高いクラスを挟むのが普通だと思う。

581:デフォルトの名無しさん
23/11/15 18:55:56.04 aqUxtLPE.net
超初心者スレで揚げ足とったり、マウントしたり

582:デフォルトの名無しさん
23/11/15 19:46:52.63 O3I3kWYX.net
>>579
何か作ってるうちに嫌でも詳しくなるよ

583:はちみつ餃子 ◆8X2XSCHEME
23/11/15 21:31:49.26 k729Xl/N.net
PC9801 時代を知ってる人は色々と詳しいと思うがその知識が役立っているというわけでもなくて、 PC9801 時代からの三十年くらいあれば詳しくなって当たり前ってだけだぞ。
たくさんの知識を身に付けるにはたくさん学ぶというシンプルな話。

584:デフォルトの名無しさん
23/11/16 11:26:46.68 QXdh7keC.net
当時は役に立ったけど今はオワコンの技術と
今でも役に立ってる技術と
どっちが割合多い?

585:デフォルトの名無しさん
23/11/16 11:55:31.84 nxuWB9A/.net
「技術は陳腐化するが考え方は永遠である」

586:はちみつ餃子
23/11/16 14:01:30.65 brAf4s3Y.net
新しい技術的流行が昔からあったやつの焼き直しってことは珍しいことじゃない。
「なんや、結局は××やないか」というときに××自体が廃れていてもう使わなくても
理解のためには役立っているのでオワコンとも役に立ってるとも言えたりする。

587:デフォルトの名無しさん
23/11/16 15:18:16.01 QXdh7keC.net
ActiveXってCOMだよね
COMってOLEだよね

588:デフォルトの名無しさん
23/11/20 15:56:09.22 QJSPRwrd.net
こんにちは坂本と申します。
C++を0から勉強したく書き込み致しました。
私ごとですが先月定年退職し、やっと自由な時間がもてる様になりました。
在職中ずっとプログラミングの勉強をしたかったのですが子育てや職場がプラントの電気機械保全業務の3交代だった為に定年後を楽しみに我慢してまいりました。
プログラミングの知識は全くなく制御盤のPLCでニーモニック語でリストプログラミングをするぐらいしか経験はありません。
有料でもかまいませんので何回でも質問ができ、すぐに返答と解説をして頂けるサービスや学習機関がございましたら教えて頂きたく書き込ませてもらいました。
漠然とした質問で申し訳ありませんが今月よりプログラミングの勉強を独学で始めましたが質問できる知り合いもいなく困り果てております。
長文失礼致しました。

589:デフォルトの名無しさん
23/11/20 19:07:01.26 UNSN9Hhc.net
>>587
DDEは?

590:デフォルトの名無しさん
23/11/21 00:24:28.42 cXhp/VaI.net
C/C++ はポインターがあるから、ややこしい。
10年やっても無理
Ruby をやれ。
半年で、Ruby on Rails も出来る

591:デフォルトの名無しさん
23/11/21 11:11:38.44 HSO31doi.net
神社code

592:デフォルトの名無しさん
23/11/21 14:22:46.70 tYm3I+7J.net
ポインターが分からない奴は
プログラムを組む資格がない

593:はちみつ餃子
23/11/21 17:27:32.66 4ADiN9xr.net
ちゃんとした本があれば独学でそんなに困らないと思うけどな。
入門書の各章をじっくり読んで理解してから次の章に進むみたいな学習法をしているなら
詰まったときにどうしていいかわからなくなりがちなのでやめたほうがいいと思う。
色んな要素が相互に絡むので順番通りに学べるようなものじゃないから。
理解できなくてもたくさん詰め込んでいけばその内に繋がりがわかってくる。
「最初は」熟考しなくてもいい。 入ってない知識が関連するなら考えてもどうせわからん。

594:デフォルトの名無しさん
23/11/21 17:38:45.53 oh7zlSJI.net
>>590
ポインタ使わないこともできるのに何言ってんだ
そもそもポインタはノイマンアーキテクチャの基本なのでポインタがわからないというならコンピュータの利点を十分に利用できないということ

595:デフォルトの名無しさん
23/11/21 18:05:44.93 tYm3I+7J.net
ポインター: 変数が入っているアドレスの数字
なんも難しいことはない

596:デフォルトの名無しさん
23/11/21 18:24:30.60 fyFN08Ef.net
インデックスって言えば分かる?
コンピュータにあるメモリー全体のインデックス番号

597:デフォルトの名無しさん
23/11/21 18:35:32.85 Ai4yJ31G.net
俺も最初全然わからなかったけどC言語ポインタ完全制覇のおかげで覚えた

598:デフォルトの名無しさん
23/11/21 19:20:18.31 JkIDzJ0A.net
Java や C# にもポインタはあるしポインタを理解できなかったら他の言語も使えないよ
ポインタ自体は難しくないんだけど C/C++ ではポインタ演算できちゃうのが鬼門なんだよね

599:デフォルトの名無しさん
23/11/21 20:49:14.51 TIZNoRj+.net
N88-BASICにポインタあったっけ?

600:デフォルトの名無しさん
23/11/21 20:53:06.63 TIZNoRj+.net
ポインタの文法なんて入門書には必ず説明があるので直ぐ分かるとして
俺が初期に読んだ数冊の入門書には
それがプログラミングでどう役に立つのかが示されてなくて
悶々としながら読んでいたなぁ

601:デフォルトの名無しさん
23/11/21 21:38:13.97 fyFN08Ef.net
ポインターなんて処理が糞遅いCPUをいかに速く動かすかって事以外に意味が無いからなぁ

602:デフォルトの名無しさん
23/11/21 23:15:10.49 mJ6deMbY.net
std::string str = "abc";
①str = str + "dd";
②str = "dd" + str;
これらの記述は有効のようです。
①の右辺はstr.operator+("dd");
と解釈でき理解できます。
②の右辺は "dd".operator+(str);
と書きかえるとこれは無効に見えます。
std::stringのoperator+のプロトタイプを調べたところテンプレートが駆使されており私では読めませんでした。
②が有効なのは、テンプレートの仕組み?でそう書けるようにつくられているからですか。

603:はちみつ餃子
23/11/22 06:21:16.63 xG0rhWaa.net
>>602
非メンバ関数として定義されている。
つまり
str=std::operator+("dd", str);
に相当することをやってる。
メンバ関数として定義すると不都合が起こるから std::complex とかも非破壊的な二項演算子は非メンバ関数として定義するのが通例だよ。

604:デフォルトの名無しさん
23/11/23 18:16:14.60 yQq1Seno.net
>>603
本を見直したらfriendにするといい等ありました。
第1引数+第2引数、という記述があり、2個の引数を持つ+演算子関数が定義されている場合はそれが呼び出される決まりになっているのですね?

605:デフォルトの名無しさん
23/11/23 18:17:35.84 yQq1Seno.net
stringから離れて一般的な質問です。↑

606:はちみつ餃子
23/11/23 20:11:53.97 V52ACnUy.net
>>604
そう。非メンバ関数として二つの演算子を受けとる operator+ があれば a+b みたいに書いたときに operator+(a,b) に読み替えられると考えてよい。
(全ての演算子を非メンバ関数として定義できるわけではない。)
余談だけど ADL という変な規則があるのは演算子が名前空間修飾できないことに対処する必要があるというのが理由のひとつで、自分が定義するクラスではこれが上手いこと作用するように設計すると便利なこともあるかもね。

607:はちみつ餃子
23/11/23 20:13:30.07 V52ACnUy.net
>>606
間違い。
「二つの演算子」じゃなくて「二つの引数」

608:デフォルトの名無しさん
23/11/23 20:15:11.03 0De2U7us.net
最小のサンプルコードを書いて自分で試すと分かるし身につくよ

609:はちみつ餃子
23/11/23 20:49:41.10 V52ACnUy.net
書いてみるというのは賛成。
でもあくまでも学んでから確かめるために書くのであって動作から言語仕様を推測したりはしないように。
C++ には未定義とか処理系定義とかがいっぱいあるからテキトーに書いたプログラムの結果が保証された動作とは限らないから。

610:デフォルトの名無しさん
23/11/25 11:27:01.67 rcrc48ZO.net
>>609
>でもあくまでも学んでから確かめるために書くのであって動作から言語仕様を推測したりはしないように。
横から悪いがこれには反対させてもらう
もちろん動作からの仕様の決めつけは良くないが、人間は学習する動物なので書いて動作を見てこそ上達するんだよ
丸暗記だけで理解したと勘違いしてるやつが昨今多い(そしてそういう奴に限って何も作ってない)ので、そういうのを後押しはしないで欲しい

611:デフォルトの名無しさん
23/11/25 11:52:38.86 rcrc48ZO.net
というか、自分の認識の間違いに気づくのもまた書いて試した時だからね(まれにコンパイラのバグだったりもするけど)
人間が頭の中で考えたことなんか穴だらけなんだから書いて試せるなら真っ先に試した方がいい

612:デフォルトの名無しさん
23/11/25 12:13:14.81 vlVh3gWj.net
>>610
同意。
処理系依存とか未定義動作なんて中級者以上になってから気にすればいいこと
はじめは手元にある処理系の結果を「正」として学習を進めても問題ないと思う

613:デフォルトの名無しさん
23/11/25 12:45:47.67 rKTwm3uz.net
>>593 これ
>>590 しね

614:デフォルトの名無しさん
23/11/25 12:47:19.78 rKTwm3uz.net
>>595-596
ポインタ判らんって人はその辺は判ってんだよ
本当に判ってないのはアドレッシングモード

615:デフォルトの名無しさん
23/11/25 12:50:17.30 rKTwm3uz.net
>>599
peek poke はあるし変数もあるから
用途という意味でのポインタはある

616:デフォルトの名無しさん
23/11/25 12:54:57.59 rKTwm3uz.net
>>610
そうだな
Rust スレにも変なのが粘着してゴリ推ししてて迷惑

617:はちみつ餃子 ◆8X2XSCHEME
23/11/25 13:45:51.01 BXmPXb0v.net
>>610
> 書いて動作を見てこそ上達するんだよ

だから書いてみるのは賛成と書いたのだが、何に反対してるんだ?

618:デフォルトの名無しさん
23/11/25 13:56:27.70 vlVh3gWj.net
「学んでから確かめるために書く」

↑反対されてるのはここでしょ

これどうなるんだろう?動かしてみよう!なるほどこうなるのか!という学び方でもいいと思う

あなたが言ってるのは「これどうなるんだろう?」ではダメで「こうなるはずだ!」と学んでから動かせってことだよね?
それは初心者には結構むずかしい

619:はちみつ餃子
23/11/25 15:39:30.62 BXmPXb0v.net
>>618
> これどうなるんだろう?動かしてみよう!なるほどこうなるのか!という学び方でもいいと思う
私が言いたいのは推測できるものではないというところが主旨で、
自分が色々やってみたことが不確かな推測であることを認識した上で
きちんとした資料にあたって確かめるという順序でもかまわないとは思うよ。
出来るのならば。
やってない人が多いように私には見えているから否定的に言ってるわけだけど。
> 初心者には結構むずかしい
訓練せずに他のことをしてても出来るようにはならないでしょ。
やらなきゃずっと難しいよ。
C++ は複雑怪奇かつ規格改訂もあるのでベテランでも頻繁に仕様を参照するのが普通なわけで、
資料を参照するのを後回しにするような人間が後にそのような人間に変われるとは思わない。

620:デフォルトの名無しさん
23/11/25 16:15:59.30 vlVh3gWj.net
「やってない人が多いように私には見えている」
多くの人が出来てないことを初心者に求めてもねェ

621:はちみつ餃子
23/11/25 16:27:29.63 BXmPXb0v.net
>>620
「推測した後には多くの人が資料を見ること」をやってないという話だぞ。
最初に資料で学ぶ人は体系的な知識が身に付くからそっちがオススメという話だぞ。

622:デフォルトの名無しさん
23/11/25 16:42:06.01 vlVh3gWj.net
初心者に対して「言語仕様を推測したりしないように」「学んでから確かめるために書く」って言ってたよね
言語仕様を理解してからコードを書けってことでしょ?

623:デフォルトの名無しさん
23/11/25 16:49:08.14 vlVh3gWj.net
>>621
先にも後にも資料(言語仕様)を確認しない人が多いんでしょ
そんな難しいことを初心者にまで要求してどうすんの

624:はちみつ餃子
23/11/25 16:51:46.77 BXmPXb0v.net
>>622
そうだよ。 言語仕様を理解してから書くのが好ましい。
理解する前に色々試すというやり方も許容しなくはないが、
それでも後では資料を見て仕様を理解するという前提があってのもの。
理解する前に色々試すタイプは資料を見なくなりがちという現実があると述べてる。

625:はちみつ餃子
23/11/25 16:55:25.38 BXmPXb0v.net
>>623
「資料」と「仕様」を使い分けて書いてるつもり。
直接に言語仕様を読めとは述べてないよ。
プログラムを書くときは色んな資料を参考にするので
入門書程度すらちゃんと読まない人がやってけると思ってんの?
ってことを言ってる。

626:デフォルトの名無しさん
23/11/25 17:00:19.64 vlVh3gWj.net
え? 資料=言語仕様じゃないの?
「言語仕様を推測したりはしないように」って言ってたから言語仕様に関する資料を読んでからコードを書けという意味だと解釈したのだけど
資料=入門書程度なの?
・・・なんか言ってることが変わってきたね?

627:デフォルトの名無しさん
23/11/25 17:03:42.33 vlVh3gWj.net
ちなみに「入門書を何冊か買って読みながら進めるといいよ」みたいな書き方だったらこんなに絡んだりしてないからね?

628:はちみつ餃子
23/11/25 17:04:18.21 BXmPXb0v.net
>>626
いや、そりゃそうでしょ。 最初から言語仕様を読めとか言わないよ。
入門書だって仕様書に基づいて書いてるし、基づいてない入門書だったらクソってだけ。

629:611
23/11/25 17:06:46.45 5Y+f+Y1g.net
>>620
これをやってきたのがはちみつ餃子なんだよ
俺ははちみつ餃子の書き込みにいつも感心してるよ

630:デフォルトの名無しさん
23/11/25 17:09:19.28 rcrc48ZO.net
>言ってることが変わってきた
うん、まぁ、はちみつはそういうとこあるから・・・w
ただまぁ、言語仕様に詳しい人の存在は(はちみつに限らず)非常に有難いんだが、
実際にソフト書く上で気にしなきゃいけないのは言語仕様だけじゃない
特定のソフトの個別の問題を解決するためのアルゴリズムについて、資料があるのか?と。(すでに出来上がってて公開されてるアルゴリズムが存在する問題などほとんど無い)
一番大事なのは論理的思考力であって、なんでもはなから資料をアテにしてたら逆にそれが身につかないよ

631:デフォルトの名無しさん
23/11/25 17:12:35.76 vlVh3gWj.net
>>628
だとしたら、言語仕様を推測するな、未定義動作や処理系がどーのこーのとずいぶんと遠回しな言い方をしたねえ
入門書を読みといいよの一言で済むのに
>>629
それは別の話。餃子がエキスパートであることは否定してない
初心者の前に高いハードルを立ててC++を聖域みたいにするのはやめて欲しいのだ

632:デフォルトの名無しさん
23/11/25 17:13:52.19 rcrc48ZO.net
どうも仕様オタク(言い方は悪いが、アマチュアという意味も込めて)な人達は、自分の知ってる世界が全てだと思い込んでるようで前々から問題だと思ってた
世の中、マイナーなAPIとかになると嘘を書いてることもあるし何も資料が無いことすらある
もちろん実際の動作から「今わかること以上」をわかった気になる(仕様を知った気になる)のは問題だが、
逆に言えば「仕様がこうだから間違ってないんだ」などと動作を確かめもせずに決めつけるのも問題だ
そういうのは結局本人の心的態度の問題に過ぎない

633:はちみつ餃子
23/11/25 17:15:51.23 BXmPXb0v.net
アルゴリズムは考えればわかることもあるかもしれんが、言語仕様は考えたってわからんし。
(想像はつくことも多いけど。)

634:デフォルトの名無しさん
23/11/25 17:17:15.50 mGx3DnG8.net
> 書いてみるというのは賛成。
初心者はこれでもいい
> でもあくまでも学んでから確かめるために書くのであって動作から言語仕様を推測したりはしないように。
中級者以上になって言語仕様等に踏み込んだ学習をしようとするなら書いたもので仕様を測るのではなく「学んで」知るべし
と言う意味だと俺は>>609を解釈してた

635:はちみつ餃子
23/11/25 17:21:04.72 BXmPXb0v.net
>>631
複雑難解な C++ を試させるのがハードルの低い方法だと主張したいわけ?
きちんと整備された学習ルートがあるという話なのにそれでハードルを上げてるとか言われるのは心外だわ。

636:デフォルトの名無しさん
23/11/25 17:24:19.67 vlVh3gWj.net
「きちんと整備された学習ルートがあるという話なのに」
お前そんな話してたか?

637:デフォルトの名無しさん
23/11/25 17:24:48.18 mGx3DnG8.net
あれよな
・初心者スレだからアドバイスはすべて「初心者向けの内容」
・初心者スレだけどアドバイスは「初心者向けの内容」と「その先を見据えた内容」
はちみつ大先生は後者だけど、ツッコミを入れたほうは前者で読み取っているから噛み合わないってだけよな、たぶん

638:はちみつ餃子
23/11/25 17:26:03.64 BXmPXb0v.net
>>636
まずは資料を読め (資料があるから) という主張を最初からしてるつもりだが。

639:デフォルトの名無しさん
23/11/25 17:34:11.58 xBFezCRv.net
「C++言語リファレンスを頭に叩き込め!!話はそれからだ」
でいいんじゃね?と俺は思っている
で、理解できない部分は入門書やサンプルコードを読んで理解する
まずは書いて試せという人もいるが俺はこの意見には賛同できない
プログラミング言語というのは日本語や英語などの自然言語と違って
少しでも間違えたら動かないし、C++の場合なら最悪システムが破壊される
理解できなくても動けばいいなどという考えの奴がいるからバグが量産されるのだ
ミスが許されないのはたとえば医者だな
医者は医者になる前に知識を詰め込むのが普通だ
知識もないのに外科手術をしたらどうなるか?
切りながら覚えろというのか?
プログラミングは手術と同様、まずは知識、次に技術が必要となる、と俺は思っている
【完】

640:はちみつ餃子
23/11/25 17:40:31.27 BXmPXb0v.net
>>637
初心者教育は二種類に大別されると思っていて、たとえば公立学校の授業でするような
興味がない層も含めて最低限の知識は与える教育と
学ぶ意欲があって専門知識と言えるようなものを身に付けようとする者に対する教育。
前者は「興味をひく」というところから考えないといけない。
理屈よりも楽しいと思えるようなやり方が必要になることもあるだろう。
後者は理屈を避けては通れない。
理屈の身に付け方には色んな方法論があるかもしれないけど
まずは書いてあるものを読め
(先人がそれを良いやり方だと思ってまとめてくれたんだから!
手を動かす必要があると思うところでは演習問題があったりもする)
という風に考えてる。
今は初心者であるかどうかは重要ではなく
ここで相談するような層は後者のルートのつもりでいると私は思って書いてる。

641:デフォルトの名無しさん
23/11/25 17:45:56.52 Xpg7OWMd.net
>>639
>理解できなくても動けばいいなどという考えの奴
誰の話?

642:デフォルトの名無しさん
23/11/25 18:21:13.32 xBFezCRv.net
>>641
わからないか…かわいそうに…
教えてあげなぁぁい

643:デフォルトの名無しさん
23/11/25 18:24:14.13 0MoP1N3f.net
おちんちん舐めてごらん

644:デフォルトの名無しさん
23/11/26 10:58:08.83 d/KzVdDP.net
>>625
最近ChatGPTに全部聴いて済ます変なのが住み着いて迷惑だな

645:デフォルトの名無しさん
23/11/26 11:15:51.84 d/KzVdDP.net
>>639
>医者は医者になる前に知識を詰め込むのが普通だ
>知識もないのに外科手術をしたらどうなるか?
>切りながら覚えろというのか?
言いたいことは判るが「最初の医者」はどうしてたんだろうな
君の言ってるやり方は「従順な職人」を育てるやり方としては正しいが
クリエイターを育てることは出来ない

646:デフォルトの名無しさん
23/11/26 12:24:07.96 t0WQFMSf.net
>>639からの>>642だからな
一見それっぽいこと言ってるようで全く中身の無い事を言うアホが長いこと住み着いてる(C++系だけなのか他もなのか)
突っ込まれると頭悪い煽り方しかしてこないからすぐわかる、玄人ぶりたいだけのアホだから相手しない方がいい

647:デフォルトの名無しさん
23/11/26 12:37:18.37 DTfcWvWZ.net
医者の下りはおかしい
医師は残念ながら完全な医学的知識を身に着けて
外科手術に臨む訳じゃないぞ
語弊を恐れなければ「切りながら覚える」側面もある

648:はちみつ餃子
23/11/26 12:54:38.94 k38CbPq9.net
ちゃんとした資料で学んでないと用語が無茶苦茶だから
何を言ってるんだかわからないということが起こる。
言語仕様の理解が結果的に正しくてもそうでなくても。
「伝わればいいだろ!」みたいに言う人が結構いるんだけど伝わらないから困るんだ。
メンバ関数をメソッドと言ったりするのは誤解の余地はそんなにないと思ってたら
非メンバ関数もメソッドと言っている例を観測したことがあるし、
子クラスって派生クラスの意味で言ってるんだよな?
と思ってよく確認したら入れ子になったクラス (nested class) だったりするし、
クラス変数は静的データメンバの意味だろう (Ruby とかにはそういう用語があるし) と思ったら
静的でないデータメンバのことを言ってたというオチもある。
結果的に正しく使ってる場面ですら本当にその意味で言ってるのか疑わしくなる。
経験や感覚で書けるようになったとしても
まともな資料を読んでないというのはそういった形でコミュニティ内で有害なわけで
たまには思い違いがあるのはしょうがないが
学んでないし学ぶ気もないのを良しとは言えないよ。

649:デフォルトの名無しさん
23/11/26 13:47:17.98 t0WQFMSf.net
>>648
いい加減にしろよ
お前何でそんな上からなの?

650:はちみつ餃子
23/11/26 14:18:15.64 k38CbPq9.net
>>649
伝えようとしない態度を批判してるところに対して伝わらないことを書くのやめろよ。
何が言いたいんだ?

651:デフォルトの名無しさん
23/11/26 14:34:29.20 mssmbX4x.net
自己正当化しか考えてない人格破綻者に道理を教えてやる気は無い、自分で考えろ
ここを利用してる初心者は、仕様について教えてくれるはちみつには感謝すべきだが、彼はプロではないしソフトウェアを書き上げたこともほぼ無いアマチュアであって
C++の学び方や上達の仕方についてまでご高説垂れてるのを真に受けないようにね
C++は別に仕様を完璧に把握しなくても使える言語だし(そんな言語なら使い物にならない)、未定義踏みまくるのは彼のようにわざと常識に沿わないおかしなコードを書きたがる素人だけだから。
荒らす気は無いのでこれで終わりにする

652:はちみつ餃子
23/11/26 14:42:52.42 k38CbPq9.net
完璧に把握しろなんて一度でも俺が書いた箇所があるなら指摘してくれよ。
書いてないことを主張したかのような風評を流してお前はなにをしたいんだ?

653:はちみつ餃子
23/11/26 14:55:17.55 k38CbPq9.net
資料(この場合は入門書)を読んでから手を動かして学ぶというごく普通の手順を主張してるつもりだが、むしろそうじゃない方法でどうするのがよいと考えてるんだ?
学校だって座学でやったことを演習で実践してるだろう。

654:デフォルトの名無しさん
23/11/26 15:50:55.41 DTfcWvWZ.net
気にするなってほぼ嫉妬なんだから

655:デフォルトの名無しさん
23/11/26 16:03:14.03 t0WQFMSf.net
>ほぼ嫉妬
俺に言ってんの?
いずれにせよ荒らそうとしてる自覚はあるか?

656:デフォルトの名無しさん
23/11/26 16:08:02.37 Dy8SO9u0.net
>>655
どう考えてもお前が荒らしじゃん
人のことをアホ呼ばわりしてるし

657:デフォルトの名無しさん
23/11/26 16:22:42.40 t0WQFMSf.net
>>639=645=659 バレバレだからwww

658:デフォルトの名無しさん
23/11/26 18:08:35.12 fCQnoW9K.net
>>652
言語仕様・未定義動作・処理系とか言ってたから完璧に把握しろに近いニュアンスだと感じた
メソッドではなくメンバ関数、用語を正しくつかわないと伝わらないとか言ってることがどんどん変わってる

659:デフォルトの名無しさん
23/11/26 18:08:55.12 4RSi5A29.net
お取り込み中すみませんが質問です
ダウンキャストという用語が是か非かです
ボクは不適切な用語だと思っていて
理由は
1) 言語の仕様に出てきていない
2) アップかダウンかについてももちろん仕様に無い
3) アップキャスト相当の操作は通常行わない
です
少なくともC++界隈でちゃんとした定義なんて出てこないですよね?

660:はちみつ餃子
23/11/26 20:14:28.93 k38CbPq9.net
>>659
仕様の中を検索してみたら何故か例示のコードのコメントとして数か所だけ upcast という用語で書いてあるんだけど……
原則としては C++ 用語ではないと考えて良いと思う。
クラスの関係をスーパー/サブだとか親/子で言うのが混乱の元という理由で基底/派生という用語になっているので
方向をアップ/ダウンで言うのもおかしな話だし。
derived-to-base convertion というような用語は仕様書の文面にもあるので
アップキャストに相当するのはこの用語のはずだけど
base-to-derived convertion という用語は出てこないので
ダウンキャストに相当する直接の用語はなさそう。
冗長でも「××から〇〇への変換」みたいな言い方が公式なんだと思う。
ところであらためて JIS を見たら derived-to-base convertion の訳語は「派生基底変換」だった……。
to が脱落したらだいぶん雰囲気が変わってしまうでないの。
これは真似しないほうがいいかもね。
ただ、 C++ 界隈の中でも、というか規格の提案や検討に関する文面の中でも
アップキャスト/ダウンキャストという用語はまあまあ使ってるっぽいので
なんだかんだで一語で表せるってのは便利なんだと思う。
私は使わないようにしているけど。

661:はちみつ餃子
23/11/26 20:20:37.65 k38CbPq9.net
すまぬ。 綴りが間違えてた。 concertion じゃなくて conversion だった。

662:デフォルトの名無しさん
23/11/26 20:28:40.49 4RSi5A29.net
レスサンクス
お手数おかけして痛み入ります
> 3) アップキャスト相当の操作は通常行わない
B *b = (B *)d; // もしもこれが必要な世界だったら
使い分ける?ための用語が欲しくなるのはまだわかるけど
D *d = (D *)b; // こっち方向にしかキャストしないんだから
区別する必要もないし、アップだのダウンだの余計なもんくっつける必要もない
…とはいえボクがいくらこう考えても
みんながそうじゃないから蔓延ってるわけで
> 私は使わないようにしているけど。
その一言で何か救われた気分になりました

663:デフォルトの名無しさん
23/11/26 20:32:07.21 4RSi5A29.net
一応補足
> B *b = (B *)d; // もしもこれが必要な世界だったら
B *b = d; // こう書くだけじゃ許されなくて

664:デフォルトの名無しさん
23/11/26 20:37:16.38 Dy8SO9u0.net
ダウンキャストって言葉は普通に使われてると思うが…
日本語版のウィキペディアなら
C++ - Wikipedia
URLリンク(ja.wikipedia.org)
に「dynamic_castは基底オブジェクトから派生オブジェクトへの変換(ダウンキャスト)を実行時に安全に行うための演算子である」とある
英語版ウィキペディアなら
Downcasting - Wikipedia
URLリンク(en.wikipedia.org)
マイクロソフトのリファレンスなら
dynamic_cast 演算子 | Microsoft Learn
URLリンク(learn.microsoft.com)
にアップキャストとダウンキャストのことが書かれてる

665:デフォルトの名無しさん
23/11/26 20:47:28.85 4RSi5A29.net
rustに至っては嘆かわしいことに
URLリンク(doc.rust-lang.org)
> pub fn downcast<T>(self) -> Result<Box<T, A>, Box<dyn Any, A>> where T: Any,
上記トレイトのメソッド名に採用されている
あー虚しい
あーヤダヤダ

666:デフォルトの名無しさん
23/11/26 20:59:53.00 mssmbX4x.net
>>664
使われてるけど規格に定義があるような正式な用語ではないってことだろ

667:はちみつ餃子
23/11/26 21:20:56.75 k38CbPq9.net
>>662
むしろアップ/ダウンだけでは状況を充分に表せないんじゃないかな。
ポインタを経由せずに値を直接キャストすることもありうるし
参照の場合かもしれない。
class foo {};
struct bar : public foo {};
int main() {
auto a = bar();
// bar から foo へのアップキャストってどれのこと?
auto b = static_cast<foo>(a);
auto c = static_cast<foo *>(&a);
auto &d = static_cast<foo &>(a);
}

668:デフォルトの名無しさん
23/11/26 21:48:36.05 Dy8SO9u0.net
>>666
一応マイクロソフトのリファレンスは正式だと思うが
まあマイクロソフト独自の規格ってなるのだろうけどな
あんなもんは認めないというのなら仕方あるまい

669:デフォルトの名無しさん
23/11/26 21:52:47.74 DTfcWvWZ.net
>>660
>仕様の中を検索してみたら何故か例示のコードのコメントとして数か所だけ upcast という用語で書いてあるんだけど……
>原則としては C++ 用語ではないと考えて良いと思う。
>クラスの関係をスーパー/サブだとか親/子で言うのが混乱の元という理由で基底/派生という用語になっているので
>方向をアップ/ダウンで言うのもおかしな話だし。
upcastとdowncastって一般名詞なのではないかな?

670:デフォルトの名無しさん
23/11/26 21:57:36.24 mssmbX4x.net
>>668
デファクトスタンダードだとは思うよ、個人的には使うことに全然否定的ではない

671:デフォルトの名無しさん
23/11/26 22:15:54.01 Dy8SO9u0.net
>>670
デファクトスタンダード
それだ
大正解

672:はちみつ餃子 ◆8X2XSCHEME
23/11/26 23:34:44.38 k38CbPq9.net
言語仕様の説明をするときには >>667 のようなバリエーションの内のどれのことを言っているかで
事情が変わってくるので結局は具体的な場合を示さなければならず、
「アップキャスト」「ダウンキャスト」という用語で充分に説明できない。
(より詳細な場合分けをするので用語を使う機会がない。)

逆に言うなら「アップキャスト」「ダウンキャスト」という用語を使うときは
充分な補足説明が必要で、それをちゃんとやってるか? ってことでもある。

どうせ説明を付け足すなら用語の甲斐がないので
使う意味もそんなにないように思う。

念のために補足しておくけど、これは「言語仕様を説明するなら」という前提なので
そうではない状況で文脈を共有できていて
「アップキャスト」「ダウンキャスト」という用語で通じるという確信がある場面に対する意見ではないよ。

673:デフォルトの名無しさん
23/11/27 04:54:45.36 tiJqQBXv.net
オナニー解答

674:デフォルトの名無しさん
23/11/27 08:10:08.19 8c8BDf1i.net
相変わらずはちみちはめんどくせーな

675:デフォルトの名無しさん
23/11/27 09:35:39.43 7/k6/GSg.net
>>648
違う言語で比較するときはそういう用語の使い方になるケースが多いと感じる
「學んでいない」のとはまた別の問題だと思う

676:デフォルトの名無しさん
23/11/27 09:39:16.20 7/k6/GSg.net
>>653
あいつは學校行ってないかも知れないな
なんでも試行錯誤で
挙句ChatGPTが完璧に教えてくれると勘違いしている
救えない

677:デフォルトの名無しさん
23/11/27 09:41:27.50 7/k6/GSg.net
>>659
「ダブルポインタ」ってのも可笑しな使われ方してることが数多く観測される

678:デフォルトの名無しさん
23/11/27 09:52:51.04 7/k6/GSg.net
>>672-674
アスペ臭を感じる

679:デフォルトの名無しさん
23/11/27 14:40:19.25 UqO8a829.net
アスペルガー症候群だって良いじゃないか?
何で差別的なことを書くのかね?

680:デフォルトの名無しさん
23/11/28 00:01:54.69 5UazaCro.net
クラス内からのみ参照する定数配列のベストな書き方を模索しています。
まず
1、constメンバ変数にする方法。ヘッダに書くだけで手軽だが、オブジェクト生成のたびに領域が取られてしまい資源浪費。
2、staticメンバにする方法。
.h
static const int TABLE[3];
.cpp
const int TABLE[3]={1,2,3};
エラー。ほかに、{1,2,3}の場所をhに移動してみたりしたがすべてエラーになり断念。
3、cppにのみに書きhには書かない。
.cpp
const int TABLE[3]={1,2,3};
エラーにならず良好。ただこれだとクラス無関係のC風の書き方なので、別の翻訳単位とよ間で名前の衝突が起きうる?
名前の衝突なく、メモリ占有はただ一個で、資源節約につながるならconstexprも活用したい。ベストな書き方はどうなりますか。
constexprは上のconstを置き換えて試しましたが2ではエラー解消せずでした。

681:デフォルトの名無しさん
23/11/28 00:04:59.65 5UazaCro.net
2のcppは
const int クラス名::TABLE[3]={1,2,3};
も試したはずですがエラー解消しませんでした。

682:デフォルトの名無しさん
23/11/28 00:37:23.98 dISnZSIc.net
2で通るはずだけどなぁ・・・ヘッダインクルードしてないとか?はさすがに無いか
あとC++17以降ならstatic constexprにすれば暗黙的にinline変数(定数)になるのでなお通るはず(宣言と同時に=ヘッダで定義できる)

683:デフォルトの名無しさん
23/11/28 01:08:09.85 dISnZSIc.net
あ、ごめん2で通るはずってのはcpp側がクラス名::TABLEの場合

684:デフォルトの名無しさん
23/11/28 06:02:30.27 fb4KLmhh.net
2、staticメンバにする方法。
.h
static const int TABLE[3]={1,2,3};
.cpp
extern const int TABLE[3];
もれはやらんけど

685:デフォルトの名無しさん
23/11/28 06:13:38.37 fb4KLmhh.net
あ、ごめん逆だった
.cpp
static const int TABLE[3]={1,2,3};
.h
extern const int TABLE[3];

686:デフォルトの名無しさん
23/11/28 10:21:56.36 tbacT9e+.net
>>681
これは通るだろ? コンパイラは何よ?

687:はちみつ餃子 ◆8X2XSCHEME
23/11/28 10:25:57.66 mRTkdYl9.net
>>681
出来なかったというコードをそのまま提示して欲しい。
状況がよくわからないのに想像で対処法を考えてもしょうがない。
コードがちょっと長くなるなら
codetter とか wandbox とか ideone とかを使って。

688:デフォルトの名無しさん
23/11/28 10:27:57.27 vcMwjchf.net
クラス内の定数を外部に生出しとかしないから
enunとかで宣言はするけど
何番目が欲しいとかはサービス関数作るしなぁ

689:デフォルトの名無しさん
23/11/28 10:30:15.59 vcMwjchf.net
つか、static宣言の内部でしか使わないものを何でヘッダーファイルに書くの?

690:デフォルトの名無しさん
23/11/28 10:32:49.40 vcMwjchf.net
ヘッダーファイルはクラスコードの名刺みたいなもんで
外部にこう言う事が出来ますよってPRする為のファイルなんだから、普通は内部で完結してるものは書かないよ

691:デフォルトの名無しさん
23/11/28 10:35:09.02 vcMwjchf.net
マジックナンバー避ける為に#defineするとかも、cpp側の先頭に書くと、全ビルドしなくて済むしな

692:デフォルトの名無しさん
23/11/28 11:07:40.67 t7+ip2Xg.net
>>689
staticには複数の意味がある

>>680 の発想は h に static 描いてみたら「たまたま」エラーが消えたら ok みたいなやり方なんだろ

693:デフォルトの名無しさん
23/11/28 11:35:51.07 vcMwjchf.net
>>692
staticより「内部でしか使わない」って話の方を拾ってね

694:デフォルトの名無しさん
23/11/28 12:43:41.53 dISnZSIc.net
>>693
質問者は「クラス内からのみ参照する」って言ってただろ

695:デフォルトの名無しさん
23/11/28 18:17:05.00 vcMwjchf.net
>>694
それならヘッダーファイルに書く必要無いやんけw

696:デフォルトの名無しさん
23/11/28 18:50:50.78 dISnZSIc.net
そら綺麗に一つのcppに全部そのクラスの実装を切り分けてるならcpp内にstaticでいいだろうけどね

697:デフォルトの名無しさん
23/11/28 20:09:09.84 vcMwjchf.net
そんな巨大なクラスは設計が間違ってないか?

698:デフォルトの名無しさん
23/11/28 20:12:44.23 bqHRuT95.net
>>677
> 「ダブルポインタ」ってのも可笑しな使われ方してることが数多く観測される

それなw
初心者ほどこの用語を使ってるように見える
初心者が集まるところでこれを流布してるやつがおるんやろな
ポインタへのポインタっていうスケーラブルな定義が理解できてなくて
アスタリスクいっこのポインタと、二個のぽいんたがある!って感じなんやろな

699:はちみつ餃子 ◆8X2XSCHEME
23/11/28 20:20:10.37 mRTkdYl9.net
>>697
この >>696 の言は逆のことを言ってると思う。
ひとつの翻訳単位にたくさんのクラス (の実装部分) を書くこともあるから
ファイルスコープにしたらスコープの範囲が広すぎる (制限にならん) やんけと言ってるように読める。

700:デフォルトの名無しさん
23/11/28 20:27:35.33 dISnZSIc.net
>>697
巨大とかじゃなくて、あんたの考えてるであろう1ヘッダに1ソースってのも指針としてはもちろん良いんだけど(そして質問者のケースに合ってるならいいけど)
例えばクラステンプレートになると、ソースに実装を書けないからヘッダのどこか(ヘッダからインクルードしてユーザーに見え辛い場所には出来るが)で実装を書くことになる
そうなるとその実装からソースファイル内のstaticな値など見えるわけがないだろ

701:デフォルトの名無しさん
23/11/28 20:29:47.21 dISnZSIc.net
>>699
もちろんそれもある

702:デフォルトの名無しさん
23/11/28 20:57:18.00 dISnZSIc.net
まぁどれを選ぶかは本人の都合だけど、クラス定義の中にprivateで書くのが自然っちゃ自然な希ガス

703:デフォルトの名無しさん
23/11/28 21:00:29.03 HOP5xTTo.net
>例えばクラステンプレートになると、ソースに実装を書けないから
C++の設計ミスだな
特にテンプレ

704:デフォルトの名無しさん
23/11/28 21:55:43.79 vcMwjchf.net
テンプレートは単なる#defineだからなぁ
あんなもん#defineでの置き換えによる副作用を引き起こす悪習の最たるもんだよ

705:はちみつ餃子
23/11/28 22:43:12.61 mRTkdYl9.net
一応はモジュールの概念の導入でちょっと良くなっているはずだが皆でこぞって移行するってほどには全然なってないからそこまで魅力的とは思われてないんやろね。
従来のスタイルと共存できるようにするのは C++ の立場では当然ではあるものの、悪い部分も捨てきれないことになりがち。
コンパイラのサポートもあまり熱心ではない(?)ような雰囲気だからそこも不安だし。

706:デフォルトの名無しさん
23/11/28 23:00:59.77 5UazaCro.net
どうも>>680です。
2のクラス名あり版でビルド通りました。
-sample.h
class sample_1 {
int a;
static const int TBL[3];
public:
sample_1();
};
-sample.cpp
#include "sample.h"
#include <iostream>
const int sample_1::TBL[3] = {1,2,3};
sample_1::sample_1() {
a = 2;
std::cout << TBL[a] << std::endl;
}
-main.cpp
#include <iostream>
#include "sample.h"
int main() {
sample_1 sa;
return 0;
}

707:デフォルトの名無しさん
23/11/28 23:06:12.31 5UazaCro.net
sample.hにTBL宣言なしで、
sample.cpp
#include "sample.h"
#include <iostream>
static const int TBL[3] = {1,2,3};
sample_1::sample_1() {
a = 2;
std::cout << TBL[a] << std::endl;
}
でもOKでした。こちらのstaticはC式の使い方ですね。
私はTBLが.hに現れない上の書き方がいいと思いますが、これを最適としてよさそうですか。

708:デフォルトの名無しさん
23/11/28 23:19:21.29 dISnZSIc.net
解決おめ、自分の用途に合うと感じるならそれがベストと思うよ

709:デフォルトの名無しさん
23/11/29 06:23:02.71 n75oaT1g.net
h に static 描くと単に相互干渉しないってだけで
インスタンスは造られまくって無駄リソース出まくるんじゃね

710:デフォルトの名無しさん
23/11/29 09:24:39.36 5+1qDy8t.net
奴は人の書き込み見ちゃいないよw

711:デフォルトの名無しさん
23/11/30 22:28:52.60 p6G1t8dm.net
sizeof(クラス名)を活用できる場面はありますか。
メンバによってはCのsizeof(構造体名)と同じ使い方ができると思いますが、
クラス一般について考えると思いつきません。
たとえば
std::string name;
がメンバ変数にあるともう、クラスのサイズは不定になりそうです。
あっ、new は・・・いや、mallocと違ってサイズ指定は不要ですね。

712:デフォルトの名無しさん
23/11/30 22:39:03.15 jq+Wc58z.net
>>711
>std::string name;
>がメンバ変数にあるともう、クラスのサイズは不定になりそうです。
確認してみましょう!

713:はちみつ餃子 ◆8X2XSCHEME
23/11/30 23:39:52.07 3QI4e6Tt.net
>>711
sizeof 演算子の適用結果は定数であることが保証される。
定数式として使うことができる。
std::string なども型の大きさが変動したりはしない。

C ではオペランドが VLA のときは sizeof の結果は定数にならないのだけれど C++ には VLA がないのでそういう例外はない。
(実際には処理系の拡張として VLA を使える場合もある。)

メモリアロケーションまわりを自分でコントロールする機会があれば普通のクラスの大きさを知る必要がある場合もなくはない。
それほど機会は多くないだろうけど。

本来 (?) の用途とは違うところで使われる場合もあって、
いわゆる SFINAE のトリックで sizeof が使われることもそれなりにある。

714:デフォルトの名無しさん
23/11/30 23:55:15.59 p6G1t8dm.net
>>713
高度な領域では使う場面はあるが、入門者には当分、なさそうですね。ありがとう。

715:デフォルトの名無しさん
23/12/01 10:06:48.86 NZuUNSBe.net
おまえら、stdとboostどう使い分けてる?

716:デフォルトの名無しさん
23/12/01 13:58:15.55 aU4DjGEJ.net
>>714
stringも実際には確保したメモリのポインタと文字列サイズを持ってるだけ(だけではないけど簡単に言えば)なので
Cの構造体と大して変わらんのよ

717:デフォルトの名無しさん
23/12/02 07:29:47.55 qIqFVuKn.net
まず鍵を与え、文字列を暗号化等して暗号文文字列を返したい。
暗号化ユーティリティ風のクラスをつくり、鍵とstringを渡す案 (1)と、stringを継承して鍵保持メンバ関数と暗号化メンバ関数を追加する案(2)を思いつきました。
どちらがでも実現できるように思いますが、何か設計のポイントはありますかね。
暗号化等には既製ライブラリ使います。

718:はちみつ餃子 ◆8X2XSCHEME
23/12/02 09:03:43.92 w8ZlbPjQ.net
>>717
設計は総合的な判断だから単発の事情では判断しづらいというのは前置きとして書いておくけど、原則的には非メンバ関数として実装するほうがよい。
というよりも継承を使うほうが悪い。
「こういうメンバ関数があると便利」ということだけが理由なら継承を使うのは好ましくない。

プロジェクトの中で使う文字列を暗号化機能付きの文字列クラスで一貫して扱うならそれはそれでそんなに悪くないけど、通常は std::string 型のオブジェクトがあってそれを暗号化したいだけなのに別の型に変換にするという手間をかけるのがユーザーにとって便利だと思う?

719:はちみつ餃子 ◆8X2XSCHEME
23/12/02 11:45:21.73 w8ZlbPjQ.net
他の選択肢としてはストリームのアダプタにするとかいう方法も思いつく。
極端に大きなデータ (メモリに格納するには無理のある大きさ) にも対処したい場合は入出力と並行して処理することになるから、普通にストリームに書き出すのと同じように使ったら勝手に暗号化されてるというのは使う側としては楽でいい。
自分が使うものならそういう余計な抽象化層を挟むのは手間なだけかもしれないし、匙加減は微妙なところ。

720:デフォルトの名無しさん
23/12/02 12:16:48.61 0tC7Yjqi.net
sqliteとかの(暗号化もあるけど)暗号化しないバージョンのDBを使ってて
書き込むとき勝手に暗号化してくれると有難いな

721:デフォルトの名無しさん
23/12/02 13:25:55.77 JgaBxQHi.net
ここはプログラム技術板だぞ 自分で作れ

722:デフォルトの名無しさん
23/12/03 06:49:36.39 xZHPSaOR.net
このスレはC++の話ではない書き込みが多すぎる

723:デフォルトの名無しさん
23/12/03 11:07:00.27 QTewqrs7.net
C++の守備範囲が広いんよ

724:デフォルトの名無しさん
23/12/03 21:36:41.23 kkqQUehZ.net
>>718
ありがとう。
非メンバ関数として実装、と見て最初はなぜ?と思いましたが、確かに文字列変換だけでクラスオブジェクトはいらないですね。
string 暗号化(鍵, 平文);
だけあれば十分だと。

725:デフォルトの名無しさん
23/12/04 21:09:04.65 wzr7hFvb.net
msys2で開発環境を作りたくて
Windows10上にmsys2をインストールしてそのうえにpacmanからmingw-w64-x86_64-toolchainの最新版をインストールして
g++でコンパイルしてHello Worldを出力するところまではうまく行ったのですが
std::ifstream ifs("hoge.txt");
のような実行ファイルと同じ場所にある、あらかじめ用意したテキストファイルを読み込むだけのコードを書いてもファイルの読み込みに失敗します。
fstreamだけの問題ではなくfilesystemあたりをインクルードして適当な関数でテストしてもファイルが存在しないことになっていました。
どこで質問するのが適切なのかも見当がつかない状態なのですが原因に心当たりがある方がもしいらっしゃったら教えて頂けないでしょうか?

726:デフォルトの名無しさん
23/12/04 22:11:21.42 +6ZMbPCa.net
エラーメッセージは?

727:はちみつ餃子 ◆8X2XSCHEME
23/12/05 00:16:37.88 z5PiblaY.net
msys2 環境は数種類のモードがあるはずだがどれで起動した?

728:デフォルトの名無しさん
23/12/05 04:57:07.09 DXGBHl1O.net
実行ファイルの場所がカレントになってないんだろ
getcwd()してみ

729:728
23/12/12 14:02:16.36 haJQSzRG.net
エラーは何もなくて変数に何も格納されてない状態だったので原因よくわかりませんでしたが
今回は>>728さんの言う通りになっていて解決できました
まだmsys2自体の仕様も十分に理解してなくて手が回っていない状態なのでこれでいったん失礼します
ありがとうございました!

730:デフォルトの名無しさん
23/12/12 15:14:22.81 bMo3JLCK.net
GUIから起動するとカレントディレクトリがホームになるんだったっけ?

731:デフォルトの名無しさん
23/12/13 15:23:50.85 Xh1qTD5r.net
OSの事情でカレントが簡単に移動してしまうのがめんどいな

732:デフォルトの名無しさん
23/12/13 16:17:33.78 b3+IUHNQ.net
プログラムの実行に必要な設定ファイルやデータファイルはカレントディレクトリではなく実行ファイルのパスを基準に決めたほうがいいね

733:はちみつ餃子 ◆8X2XSCHEME
23/12/13 17:12:54.61 vPv7AHCs.net
設定ファイルの類いは AppData フォルダに置くのがこのましいということになってる。
アプリケーションインストール用のフォルダ Program Files は書き込み権限が制限されているからそこに設定ファイルは置けない。
逆にどうしてもアプリケーションと設定ファイルを同じフォルダに置きたいなら Program Files にはインストールできない。
Msys2 内で使うソフトならホームディレクトリ (windows のホームディレクトリではなく msys2 が設定するホームディレクトリ、環境変数 HOME で取得できる) に設定ファイルを置くのが基本的な習慣。


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