0からの、超初心者C++相談室at TECH
0からの、超初心者C++相談室 - 暇つぶし2ch536:デフォルトの名無しさん
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 で取得できる) に設定ファイルを置くのが基本的な習慣。

734:デフォルトの名無しさん
23/12/13 17:14:51.41 Xh1qTD5r.net
起動時の引数や 自分のフルパスを取得するAPI経由で
実行ファイルのある場所を基点にどうこうすることが多いわ (Windows

unix だと usr と bin で分ける文化があるからそういうのはどうなってるんやろか
起動時のカレントのまま?

735:デフォルトの名無しさん
23/12/13 17:20:10.83 b3+IUHNQ.net
>>733
それはインストーラー使うアプリでしょ?
XCOPYインストールアプリの話だよ

736:デフォルトの名無しさん
23/12/13 17:23:03.86 HyXW4bJ5.net
カレントじゃ無くて、アプリが実行されたディレクトリに一緒に置いとくもんだろ?
ユーザー毎に違う設定にしたいなら、各ユーザーのホームディレクトリだろ?

737:はちみつ餃子
23/12/13 18:03:20.75 vPv7AHCs.net
>>736
基本的にはそうだけどパッケージマネージャの管理方式との相性があったりする。
scoop で管理するなら設定ファイルも含めてひとつのフォルダに入れるほうが都合が良いと思う。
Msys2 内で pacman で管理するなら unix 風の流儀のほうが自然だし。

738:デフォルトの名無しさん
23/12/13 23:12:49.25 zjCiNOvz.net
グローバル位置に宣言したオブジェクトはmain前にコンストラクタが実行されますね。
仕様ではmain前に実行ということのほかに何か規定はありますか。
ある処理系で、main先頭である処理を呼び出すと成功するが、その処理を上記のコンストラクタから呼び出すと失敗するということがありました。

739:はちみつ餃子 ◆8X2XSCHEME
23/12/14 00:23:02.09 GWgG2Hfk.net
>>738
ややこしい規則が色々あってここには書ききれないがおおざっぱにはこんな感じかな。

・ 定数初期化が終わってから動的初期化がされる
・ 動的初期化でも条件が揃ったときは静的初期化扱いで早めに初期化する最適化をしてもよい (しなくてもよい)
・ 翻訳単位内の初期化順序は定義が現れた順序
・ 翻訳単位をまたぐとどちらが先に初期化されるかは規定されていない

特に翻訳単位を跨いだら決まってないってのは引っかかりがちなポイントで、
強い依存関係のあるものはあまり細かく分割しないほうがやりやすいと思う。

740:デフォルトの名無しさん
23/12/14 01:04:36.74 X6Ol8Z5z.net
普通は、WSL2 でLinux を使う

MSYS2/MinGW の利点は、
hypervisor で、2つのOS を起動しないから軽い

WSL2 では、Linux側から、Windows 側のアプリも起動できる。
ただし例えば、powershell ではなく、powershell.exe と拡張子も付ける

例えばpowershellで、Windows側のフォルダ内の一覧を表示して、Linuxのgrep で絞り込む

/mnt/c/Users/ユーザー名/Documents$ powershell.exe ls | grep クイ

出力
d----- 2015/10/13 13:52 クイズ

VSCode の拡張機能・Code Runner は、
右クリックメニューから、選択したコード、またはファイル全体を実行する

この設定をチェックしておく
Code-runner: File Directory As Cwd
Whether to use the directory of the file to be executed as the working directory.

そうすると実行時にcd で、そのファイルがある場所へ、カレントディレクトリを移動してから、
そのファイルをコンパイルして実行する

設定項目、executorMap には、多くの言語の実行コマンドが書いてある。
"code-runner.executorMap": {

"c": "cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"cpp": "cd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",

741:デフォルトの名無しさん
23/12/31 22:48:46.98 tpduSr4A.net
相談室から誘導されたのでこちらで
スレリンク(tech板:104番)

buf_にPODではないオブジェクトが含まれる可能性がある場合、この領域をどのようにcopyしたりmoveすればよいでしょうか?

742:デフォルトの名無しさん
24/01/01 01:29:30.25 /rCM9JK/.net
このスレッドはゼロからC++と言っているが、C言語を知っている前提になっているよなw

743:デフォルトの名無しさん
24/01/02 11:00:49.80 TDOOgc4U.net
ワシも割と長く底辺コピペプログラマだけどなんでそんな詳しくなれるの?ってなる
有能と俺みたいな無能はどこでプログラマの生き方をたがえたのか

744:デフォルトの名無しさん
24/01/02 20:21:16.21 G9bvfkvl.net
>>743
頭の出来で決まっているからね
義務教育レベルで脱落した人間、日本語能力に問題がある人間は、プログラマーとしても問題がある。

745:はちみつ餃子
24/01/02 21:40:20.68 RkRzwbey.net
知識は入れないと増えないというすごく当たり前の話。
長く放置してたら勝手に増えるなんてことはないよ。

746:デフォルトの名無しさん
24/01/03 08:18:02.54 3n4RUKo6.net
ガキの頃からマイコンBASICマガジン見てたけど
PCなかったしポケコンはあったからたまにあるポケコンゲームのソースをポチポチ入力してたけどそれで何かの知識になったか言われたら何にもならんかったな

747:デフォルトの名無しさん
24/01/03 08:26:31.48 uKn1SmuA.net
糞コテが

748:デフォルトの名無しさん
24/01/03 13:07:46.32 3mJitcl/.net
>>746
SHARPのポケコンでマシン語使ってシューティングゲーム作ったけど?

749:デフォルトの名無しさん
24/01/03 13:17:11.92 SgwYv7hO.net
ポケコン触ってたころが一番楽しかったです
手の中に物理キーボードと実行環境があるんだもん
一生遊べるよ

750:デフォルトの名無しさん
24/01/03 14:56:53.56 giTORTIB.net
>>741
memcpyでなくちゃんとplacement newでコピーorムーブコンストラクタ走らせればいんじゃね?

751:デフォルトの名無しさん
24/01/10 03:00:04.91 lNNg6PiH.net
Class Hogeの中でたくさんのFugaを管理するために
std::vector<std::unique_ptr<Fuga>>というメンバ変数を作りました
可変長引数テンプレートで複数のstd::unique_ptr<Fuga>を受け取るコンストラクタを書こうとしたのですが
std::unique_ptrがコピー禁止のためうまくいきませんでした。
Hoge(Args&&... args)
という形で右辺値参照を受け取ってうまいことムーブしてClass Hogeを初期化する方法ってありますか?

752:はちみつ餃子 ◆8X2XSCHEME
24/01/10 04:36:30.64 BOjhYgCx.net
>>751
できると思うけど、何をやりたくて何が上手くいかなかったのかイマイチわからない。
出来なかったコードをみせて。

753:デフォルトの名無しさん
24/01/10 11:27:22.10 lNNg6PiH.net
>>752
class Fuga
{
int placeholder;
};
class Hoge
{
public:
std::vector<std::unique_ptr<Fuga> > vec;
template<class... Args>
Hoge(Args... args)
{
vec = {args...};
}
};
int main()
{
/*Fugaを何個か作成*/
auto p1 = std::make_unique<Fuga>();
auto p2 = std::make_unique<Fuga>();
auto p3 = std::make_unique<Fuga>();
/* 中略 色々処理
処理が終わったらHogeの中にFugaをまとめて放り込みたい*/
Hoge hoge(p1,p2,p3);
}
こういうものを書いたらunique_ptrがコピー禁止でエラーになったのでムーブにしたいけど書き方がわかりませんでした。

754:はちみつ餃子 ◆8X2XSCHEME
24/01/10 12:45:18.04 BOjhYgCx.net
>>753
この場合は initializer_list が問題。
initializer_list を経由するとムーブ可能/コピー不可な型を扱えない。
initializer_list を経由しない形にすればよいので要素を emplace_back で
入れる形にするなどの対処法が考えられる。

#include <memory>
#include <vector>

class Fuga {
int placeholder;
};

class Hoge {
public:
std::vector<std::unique_ptr<Fuga> > vec;
template <class... Args>
Hoge(Args&&... args) {
(..., vec.emplace_back(std::forward<Args>(args)));
}
};

int main() {
/*Fugaを何個か作成*/
auto p1 = std::make_unique<Fuga>();
auto p2 = std::make_unique<Fuga>();
auto p3 = std::make_unique<Fuga>();
/* 中略 色々処理 */
// std::move で右辺値にキャスト
Hoge hoge(std::move(p1), std::move(p2), std::move(p3));
}

755:デフォルトの名無しさん
24/01/12 09:52:36.06 Umd8uX9b.net
c++で日本語の連想配列ってあります??

756:デフォルトの名無しさん
24/01/14 15:30:33.22 O4q5V5KL.net
>>755
std::mapじゃだめなん?

757:デフォルトの名無しさん
24/01/16 21:37:05.24 eUaXJLuy.net
>>754
無事に動作させることができました。ありがとうございます!

758:デフォルトの名無しさん
24/01/20 18:17:15.80 9qysS+ur.net
時間のかかる処理があり、それが現在のスレッドをブロックして欲しくないので
その処理の部分に関してstd::async()の利用を検討していますが、
これって戻り値(future 型)でモニターしないといけない感じですか?
上記の処理はいつ終わるかは気にしないので別スレッドに投げっぱなし?で構わない
のですが... pthread_detach()的な?

759:はちみつ餃子
24/01/21 12:43:25.73 4rk7TZPC.net
>>758
std::thread のメンバ関数に detach はあるけど、期待するのはこういうこと?
ただ、メインスレッドが終了すれば他のスレッドが稼働中でもプロセス終了処理に入るし、
プロセス終了処理の中で標準ライブラリの後始末している最中に他のスレッドが
標準ライブラリを使うようなことがあると破綻するかもしれない。
強引に終わらせて良いなら std::quick_exit で即死させるという方法も取れるが、
基本的にはプログラムを終わらせるときには全てのスレッドを終了させて (終了を待って) おくのが
普通だと思う。

760:デフォルトの名無しさん
24/01/21 21:48:26.38 zlvjOB5M.net
>>758ですが、お返事ありがとうございます。

はい、とりあえず thread::detach() を使うようにしました。1つの疑問は、
URLリンク(ja.cppreference.com) によると
> ただし、その共有状態が std::async によって作成され、まだ準備完了になっておらず、これがその共有状態への最後の参照である場合は、ブロックする可能性があります。

ええ何それ、というのが発端でした(後出し失礼)。

確かに、メインスレッドの終了時のこともありますし、スレッドの後始末をちゃんと
した方が本当はいいように思われます。処理が長時間たっても終了しない場合
タイムアウトさせたりとかも。
何かシステマティックな方法等あるでしょうか。参考になるものがあれば...

761:はちみつ餃子
24/01/22 12:54:36.50 T1sqP3ZB.net
>>760
メインスレッドの終了直前でまずは適当にフラグを立てた上で他のスレッドの終了まで待機する。
重い処理をしているスレッドの側で完了ではないにしても区切り良く終われるポイントでフラグを読んで
フラグが立っていれば後始末ルートに入ってスレッドを終了させる。
その結果としてメインスレッドの待機状態が終わってプロセスの終了。
というのが普通の大まかな流れだと思う。
その上で待機時間があまり長すぎるようだと強引にでも終わらせるとかの処理を入れるかも。
std::async は既存の関数を非同期化するちょっとしたユーティリティという立場なんじゃないかな。
それで事足りるときは便利で簡単だけど、細かい制御を勝手にやってくれるわけでもないし、
やろうとするとちょっとイマイチって感じ。

762:デフォルトの名無しさん
24/01/28 11:52:43.80 W0uCnQb3.net
質問なのですがどんな環境(ロケール設定)のPCで動かしても
数値や時刻の入出力を修飾無し(12345 が 12,345 になったりしない)にする完璧な方法って次の3行で良い?
 setlocale(LC_ALL, "");     // printf()、scanf()に反映
 _wsetlocale(LC_ALL, L""); // wprintf()、wscanf()に反映 (※ 環境依存。左記はWindowsの場合
 std::locale::global(std::locale("", std::locale::all));  // cout、wcout、cin、wcin、ostringstream、wostringstream、...etc. C++の全部に反映
あとなんか実験する限り
 cout.imbue(std::locale(""));
 std::locale::global(std::locale("", std::locale::all));
とするとcoutが修飾有りとなり、cout.imbue()で与えた設定をstd::locale::global()が上書きしないように見えるのですがそういうもの?

763:はちみつ餃子
24/01/28 13:12:39.75 hRRbWEE/.net
>>762
言語仕様通りならそれらの関数を呼び出さないようにすれば環境に固有の表現の変換はしない。
std::setlocale の設定が C の標準関数の挙動に影響するのはその通り。
ただし、様々な環境での「同じ動作」を期待するなら "C" を与えるべき。
空の文字列を渡した場合には環境に固有の設定であり、通常はシステムの設定が反映される。
プログラムは起動したときに setlocale(LC_ALL, "C"); 相当の状態なので、普通は書く必要もない。
std::locale::global での設定は C++ の標準ライブラリの挙動に影響するだけでなく std::setlocale での設定にも反映されるので両方を呼び出す必要はない。
これもプログラム起動時のロケール設定は "C" 相当になっているのでそれで良ければ呼び出す必要もない。
ただし、 std::locale::global に与える設定が名前を持たない場合 (つまり std::locale("") のような場合) は std::setlocale 相当の変更もするかどうかは規定されない。
imbue はストリームにロケールを結びつけるのでグローバル設定とは独立して機能する。

764:デフォルトの名無しさん
24/01/28 14:11:55.68 eBJAlicu.net
クラスオブジェクトの代入文に、=による単純コピーと、=演算子関数による独自コピーのどちらを使うか迷います。
たとえばメンバ変数が基本データ型の集まりなら単純コピーでいい。
今出くわしたのはメンバ変数がstd::array<int, 3>の場合で、まあたぶん単純コピーでよさそう?じゃあstd::vector<myclass>なら?などと疑問が深まります。
あとコピーコンストラクタによる初期化も合わせて考える必要がありそう。

765:はちみつ餃子
24/01/28 14:36:51.31 hRRbWEE/.net
>>764
単純コピーってのは何のこと?
デフォルトで生成される代入演算子の意味で言ってるのかな?

766:デフォルトの名無しさん
24/01/28 15:36:35.20 W0uCnQb3.net
>>763
レス㌧クス、
>ただし、様々な環境での「同じ動作」を期待するなら "C" を与えるべき。
なるほど "C" ですたか、これか↓
URLリンク(www.ibm.com)
>普通は書く必要もない。
実はウィンドーズでUnicodeで出力する場合限定かもですだが、ロケール設定しないままだと
日本語OSでも漢字が表示されなかったり(L"Hello World! 漢字" → 表示: Hello World! )
英語OSに持っていったら L"Hello World! 漢字" が丸ごと出なかったり……orz
まあ漢字はこの際どうでも良いので、ロケール設定 "C" で行こうと思いまつ

767:デフォルトの名無しさん
24/01/28 16:37:46.15 eBJAlicu.net
>>765
そうです。

768:はちみつ餃子
24/01/28 16:38:46.52 hRRbWEE/.net
>>766
Windows での話か……。
msvcrt だとどうにもならなくて ucrt でちょっとマシになってるみたいな話題をこないだ Teratail で見たぞ。

769:はちみつ餃子
24/01/28 16:52:54.16 hRRbWEE/.net
>>767
デフォルトで生成される代入演算子は全てのサブオブジェクト (基底とデータメンバ) を
代入演算子でコピーするのと同じ挙動になることになってる。
基底やデータメンバが適切に代入演算子を定義されているのならデフォルト生成にまかせてよいことが多い。
注意を払う必要がある典型的なものは生ポインタで、
ポインタをコピーしても指してる先のオブジェクトはひとつだから
そのへんの扱いはデフォルト生成だとあかんことになる。
あとは外部のリソースと結びついているオブジェクトだと単純にコピーできないか、コピーさせないこともあるな。
分かりやすい例で言うなら std::thread なんかはスレッドを抽象化したものだけど
オブジェクトをコピーしたらスレッドもぽんぽん増えるなんてことになっても困るし
スレッドひとつに対応しているオブジェクトがいくつもあるようでも困るのでコピーできないようになってる。
それぞれに事情があるので明瞭な判断基準があるわけじゃないけど、
デフォルト生成の結果がほんまに自分の意図通りに動作するか考えてみて
あかんなら自分で書くしかない。

770:デフォルトの名無しさん
24/01/28 17:03:17.17 eBJAlicu.net
>>769
いつもありがとうございます。
たいていはデフォルトでよさそうですね。
std::vectorは可変長配列ってことなので、<int>であってもデフォルトでいいのかなと心配に…あこれはvectorのほうで独自=定義されてるなら問題ないわけですね。

771:デフォルトの名無しさん
24/01/30 20:47:22.29 RcbbllHt.net
bだけ通らないのが納得いかない…。
#include<iostream>
#include<functional>
using F = std::function<void()>;
void f0(){}
F f1;
class X {
F f;
public:
X(const F& f_) : f(f_){}
X& operator=(const F& f_){f = f_; return *this;}
};
int main(){
X x1(f0); // a:OK
X x2 = f0; // b:NG(conversion from ‘void()’ to non-scalar type ‘X’ requested)
X x3 = f1; // c:OK
x1 = f0; // d:OK
}

772:はちみつ餃子
24/02/02 00:09:46.55 BQKaaqcl.net
>>771
std::function ではなくごく単純なクラスでもエラーを再現できる。
暗黙の変換は原則としては多段には起こらず、 X→Y, Y→Z な変換が可能なときでも X→Z な変換はしない。 (プリミティブな型変換とクラスの型変換が連鎖することはある。)
以下の例だと X x1(1); という宣言のときに必要な「暗黙の変換」は int から foo という一段のものだけど X x2 = 2; としたときに必要なのは int から X だから一段の変換ではできない。
struct foo {
foo(int x) {}
foo(const foo&) = default;
foo(void) = default;
};
foo f1;
class X {
foo f;
public:
X(const X&) = default;
X(const foo& f_) : f(f_) {}
X& operator=(const foo f_) {
f = f_;
return *this;
}
};
int main() {
X x1(1); // a:OK
X x2 = 2; // b:NG(conversion from 'int' to non-scalar type 'X' requested)
X x3 = f1; // c:OK
x1 = 3; // d:OK
}

773:デフォルトの名無しさん
24/02/02 11:28:24.45 xohFoxUO.net
>>772
横からだけども
> X x2 = 2; // b:NG(conversion from 'int' to non-scalar type 'X' requested)
って
X x2(2);
と同義じゃねーの?

774:はちみつ餃子
24/02/02 12:19:41.13 BQKaaqcl.net
>>773
違うよ。
C++ では引数ひとつのコンストラクタは変換コンストラクタとして「も」使うことになっているから
違う文脈でも結果的に同じコンストラクタが呼び出されることになるけど
構文糖というわけではなくて違う解釈を経ている。

775:デフォルトの名無しさん
24/02/02 12:28:48.56 xohFoxUO.net
細かいなぁ

776:はちみつ餃子
24/02/02 18:32:30.30 ZFQgO+dm.net
動くなら同義と考えても大した問題じゃないが、
ここでは実際に結果が違う (一方はエラーになる) ことの説明だから……

777:デフォルトの名無しさん
24/02/02 22:30:30.14 d8Flt8Cn.net
これはなぜエラーになるのですか。
std::string s = "abc";
char name[10] = s.c_str();

error: array must be initialized with a brace-enclosed initializer


次と同等とみなせないのはなぜ?
char name[10] = "abc";

778:774
24/02/03 05:00:19.85 vGyzbOvf.net
>>772 774だけどありがとう。暗黙だと変換が途中で途切れるかもなのか。
一番通って欲しいのがbなんだけど難しいっすね…

779:デフォルトの名無しさん
24/02/03 05:21:33.46 4Ieoi/Xm.net
>>777
c_str()が返すのはchar*
char name[10] = "abc"; は特別扱いで char name[10] = {'a', 'b', 'c', 0}; と同じ
cの時からある雀の涙猫の額ばかりの文字列サポート

780:はちみつ餃子 ◆8X2XSCHEME
24/02/03 08:35:44.53 Sz70frqK.net
>>778
少し表現を変えて良ければ >>771 の X x2 = f0; を
X x2 = {f0}; と書くことでも通すことは出来るよ。

更に真面目に対処するならこんな感じかな。
URLリンク(wandbox.org)

781:デフォルトの名無しさん
24/02/03 22:40:06.88 mzdZy5dk.net
>>779
あーそういうことですね。ありがとう。

782:774
24/02/04 02:54:38.53 1VXaeA8L.net
>>780 上は={}で通るのは確認してました。{}付けるとX型に見なされてコピーコンストラクタで初期化されるで合ってますか?
下の方、typenameの所は余りよく分からなかったですが強制的に引数の型で包んで(オブジェクト生成?)、コンストラクタの引数代入時に変換追加するということでいいですか?
typename以下はdecltype(f_)((f_))でも良いんかなと思って変更してみたら通りました

783:はちみつ餃子
24/02/04 09:54:01.38 /H29LerN.net
>>782
> {}付けるとX型に見なされてコピーコンストラクタで初期化されるで合ってますか?
いいえ。 直接初期化に該当します。
コピー (コピーコンストラクタの起動) は発生しません。
つまり X x1(f0); と書いた場合と同じということです。
ですから暗黙の変換を一段階すれば充分なのでエラーなく通ります。
> コンストラクタの引数代入時に変換追加するということでいいですか?
いいえ。 何もしません。
コンパイルを通すためには不要ですので、 X のコンストラクタは
template <class T>
X(const T& f_) : f(f_) {}
という定義だけでも問題なく動作します。
ただ、こうすると T は「あらゆる型」になりえます。
std::function<void()> に変換不可能な型も受け入れてしまうということです。
変換不可能であればいずれにしても最終的にはエラーなのですが、
X がデタラメな型も受け入れてから F に変換失敗してエラーになるよりは
特定の条件を満たす型以外を X が拒否するほうが一般的には都合がよいので
そうなるようにしたのです。
コンパイルを通すために必要なのではなく通さないための処置です。

784:774
24/02/04 22:33:14.16 1VXaeA8L.net
>>783 上:初期化周りは似たような物が色々あって知識が曖昧でした。
下:あの記述は型制限の為ですか。読んでも意図がよく分からなかったので助かります。
説明ありがとうございました

785:デフォルトの名無しさん
24/02/10 13:14:08.12 KJGevrBa.net
質問なのですがstd::coutに対する
 (a) 固定小数点表示
 (b) 小数以下精度指定(例えば20桁
 (c) setw()される表示幅に対し足りない上位桁0埋め
という表示仕様への変更と復旧は、変更が
 auto sv_flags = cout.flags(); cout << std::fixed; // (1)
 auto sv_prec = cout.precision(std::streamsize(20)); // (2)
 auto sv_fill = cout.fill(); cout << std::setfill('0'); // (3)
復旧が
 cout.flags(sv_flags); // (1)の変更から復旧
 cout.precision(sv_prec); // (2)の変更から復旧
 cout << setfill(sv_fill); // (3)の変更から復旧
と書くのが普通?シグネチャが不統一な印象があるますがもっとズバっとやる方法は無いもの?
((1)は変更にcoutのメソッドとマニピュレータが両方要り、復旧はcoutのメソッド。
 (2)は変更も復旧もcoutのメソッドで済む。(3)は変更が(1)と同じパティーンで復旧がマニピュレータ……

786:はちみつ餃子
24/02/10 14:30:14.27 XEL9SE6k.net
>>785
・ 直接的に入出力を司るのはバッファと呼ばれるオブジェクト
  (たとえば basic_streambuf など)
・ ストリームには対応するバッファがセットされている (あまりバッファを直接には操作しない)
・ 書式はストリームの状態として保持されている
つまり同じバッファ (出力先) に対して異なるストリームをかぶせることが出来る。
一時的にだけ書式を変更するのであれば一時的なストリームを作るという方法がとれる。
コードで例を出すならこんな感じ。
#include <iostream>
int main() {
std::cout << 0.1 << std::endl;
{
std::ostream temp(std::cout.rdbuf());
temp.precision(30);
temp << 0.2 << std::endl;
temp << 0.3 << std::endl;
}
std::cout << 0.4 << std::endl;
}
書式をストリームの状態として持つのがすこぶる不格好だというのは
C++er にとっての共通認識になっていてようやく C++23 から std::print が導入されたので
モダンな C++ を使えるならそっちを使ったほうが良い。
std::format なら C++20 から。

787:デフォルトの名無しさん
24/02/10 15:00:10.91 KJGevrBa.net
>>786
㌧クスなるほど……
変更した書式の戻し忘れが無く、問題らしい問題点はほぼ無しで良さげ……
(しいて言えばstreamの中の作りを理解していなければtempが何の目的でそうするのかわかりにくい(コメント必須)なだけ、
std::printは手元のVC++がまだC++20対応止まりなので当面見送らざるおえない
std::formatは…… 書式文字列が定数式限定という仕様のはいかがなものか……
今回の用途では困りませんし、コンパイル時に書式の妥当性をチェックしてくれるのは良いのですだが、
仮に、C言語における自作printf()様インターフェースの関数(書式文字列と可変長引数を変数で受け取り、内部でvprintf()を呼ぶ)
みたいなものを作りたくなった場合どうするんじゃとそこはかとなく疑問が……

788:はちみつ餃子
24/02/10 15:16:22.24 XEL9SE6k.net
>>787
実行時バージョンとして std::vformat も用意されている。

789:デフォルトの名無しさん
24/02/10 15:25:38.54 KJGevrBa.net
>>788
なるほどなるほど、自作std::format()様関数は問題無く作成でき、
書式文字列が定数式限定が困るというのは杞憂ですたねサーセン;;;
(実行時にならないと書式文字列が決まらない場合、コンパイル時チェックが原理的に不可能になるのはC言語のprintf()/vprintf()の関係も同じなのでC言語からの後退ではない

790:はちみつ餃子
24/02/10 16:29:24.58 XEL9SE6k.net
メンバとして copyfmt があって、これで書式を他のストリームにコピーすることも出来る。
書式を待避しておくだけのストリームを作ってそれにコピーしておいて
後で元に戻すという使い方をしてもいいんだけど、
どうせストリームをあらたに作るならそれを一時的なストリームとして使ったほうが自然かと思う。

791:デフォルトの名無しさん
24/02/11 22:38:22.35 smEWrSvv.net
std::setのinsertで

std::set<int> c1 = {1,2,3};
std::set<int> c2;

c2.insert(c1);

と書けると便利に思えますが解説のページを見るとできないようです。
なぜですか。

792:デフォルトの名無しさん
24/02/11 22:45:16.04 KNbj1ANO.net
>>791
c2.insert(c1.begin (), c1.end ());

793:はちみつ餃子 ◆8X2XSCHEME
24/02/12 11:50:11.55 4VueJhli.net
>>791
set に set を insert できる「だけ」ってのはあまり便利ではない。
集合というものをより汎用的に扱える枠組みとして C++20 から range という概念が導入された。
その枠組みを上手いこと成立させる言語機能 concept が長いこと検討されてて、
入る入ると言いながら C++20 までずれ込んでしまったという事情がある。

そんなわけで、 C++23 からなら insert_range が使えて、
これは range の条件を満たすものならなんでも受け入れられることになってる。

794:デフォルトの名無しさん
24/02/12 21:37:56.53 WngRm50l.net
>>791
c2.merge(c1) ※C++17以降

795:デフォルトの名無しさん
24/02/13 22:11:49.56 TA8E1xmn.net
みなさんありがとう。環境適合を優先して>>792を使うことにします。

796:デフォルトの名無しさん
24/02/18 00:05:28.51 AtsZxBPF.net
コンストラクタの初期化子リストの中で、どこまで柔軟に記述できるのかなーと思ってGPT先生に聞いたら、constまたはconstexprを返す関数のみ書けるとのことでした。
コンストラクタ内部のように好きなように書けないとわかり、初期化子リストの価値が低く感じられました。
そんな制限を設けてまで初期化子リストを導入した意図は何でしょう。

797:デフォルトの名無しさん
24/02/18 01:13:17.69 UTNyRtZE.net
ChatGPTなんかあてにするな、平気で間違ったこと言うんだから
constやconstexpr以外を返す関数だって普通に呼べる
試しにChatGPTに「メンバ初期化子リストではconstかconstexprを返す関数しか呼べませんが、これはなぜですか?」ってあえて間違った前提条件で質問してみたら、間違ってることに対する指摘は一切なかったし、さもこっちの質問が正しいかのようなそれっぽい返答が返ってきたし
---
俺:
C++において、コンストラクタのメンバ初期化子リスト内ではconstまたはconstexprを返す関数しか呼ぶことができません。これはなぜでしょうか?
ChatGPT:
C++において、コンストラクタのメンバ初期化子リスト内でconstまたはconstexprを返す関数しか呼ぶことができる理由は、初期化子リストがオブジェクトの初期化に使用され、実行時のコードが生成されないためです。メンバ初期化子リストはコンストラクタの一部であり、オブジェクトが生成される際に実行されます。このリスト内での関数呼び出しはコンパイル時に解決され、オブジェクトの初期化に関する情報は実行時に生成されません。
constまたはconstexprを返さない関数をメンバ初期化子リスト内で呼ぶと、実行時にコードが生成される可能性があります。しかし、これはオブジェクトが生成される前に行われる初期化の一環であり、実行時の処理としては不要なオーバーヘッドを引き起こす可能性があります。
コンストラクタのメンバ初期化子リストは、メンバ変数を適切に初期化するためのものであり、できるだけ効率的に行われるように設計されています。そのため、コンパイル時に解決されるconstまたはconstexprを返す関数の呼び出しに限定されています。
---
だからAIをあてにしちゃダメだよ

798:デフォルトの名無しさん
24/02/19 00:17:49.94 bJlSKdBs.net
>>797
私が聞いたときも似たような内容が含まれていて、そうなんだねと納得してしまいました。
ではコンストラクタに書けることはすべて書けるのですね。
なおこの問いは、入門書籍にはそこまで書かれてなくて、検索でもかんたんに見つからなかったので聞きました。

799:はちみつ餃子
24/02/19 02:33:45.03 j7eyydGe.net
>>798
たぶん >>796 で言う「初期化子リスト」は「メンバ初期化子リスト」だよね?
これらは全くの別物。
明らかに混同しやすい用語だから仕方がない部分はあるんだが、
誤った用語を元に調べたら誤った解説に当たりやすいかもしれない。
メンバ初期化子リストは直接初期化 (direct-initialization) であると規定されていて
具体的な挙動の説明は初期化の章に丸投げされている。
URLリンク(timsong-cpp.github.io)
つまりメンバ初期化子リストに特有の事情というものはない。
普通に初期化なんで、そこに違いがあるかもしれないという想像をする人がいてそういう人のために
違いが無いと断りを入れる必要があるとは入門書の著者は思わなかったんだろう。
有るものを有ると説明することはあるが無いものを無いと殊更に強調して説明はあまりしない。


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