0からの、超初心者C++相談室
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2018/11/12(月) 14:55:13.35ID:Tf74ZWQr 何にも知らない0からの出発、超初心者のためのC++相談室
682デフォルトの名無しさん
2023/11/27(月) 14:40:19.25ID:UqO8a829 アスペルガー症候群だって良いじゃないか?
何で差別的なことを書くのかね?
何で差別的なことを書くのかね?
683デフォルトの名無しさん
2023/11/28(火) 00:01:54.69ID:5UazaCro クラス内からのみ参照する定数配列のベストな書き方を模索しています。
まず
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ではエラー解消せずでした。
まず
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ではエラー解消せずでした。
684デフォルトの名無しさん
2023/11/28(火) 00:04:59.65ID:5UazaCro 2のcppは
const int クラス名::TABLE[3]={1,2,3};
も試したはずですがエラー解消しませんでした。
const int クラス名::TABLE[3]={1,2,3};
も試したはずですがエラー解消しませんでした。
685デフォルトの名無しさん
2023/11/28(火) 00:37:23.98ID:dISnZSIc 2で通るはずだけどなぁ・・・ヘッダインクルードしてないとか?はさすがに無いか
あとC++17以降ならstatic constexprにすれば暗黙的にinline変数(定数)になるのでなお通るはず(宣言と同時に=ヘッダで定義できる)
あとC++17以降ならstatic constexprにすれば暗黙的にinline変数(定数)になるのでなお通るはず(宣言と同時に=ヘッダで定義できる)
686デフォルトの名無しさん
2023/11/28(火) 01:08:09.85ID:dISnZSIc あ、ごめん2で通るはずってのはcpp側がクラス名::TABLEの場合
687デフォルトの名無しさん
2023/11/28(火) 06:02:30.27ID:fb4KLmhh 2、staticメンバにする方法。
.h
static const int TABLE[3]={1,2,3};
.cpp
extern const int TABLE[3];
もれはやらんけど
.h
static const int TABLE[3]={1,2,3};
.cpp
extern const int TABLE[3];
もれはやらんけど
688デフォルトの名無しさん
2023/11/28(火) 06:13:38.37ID:fb4KLmhh あ、ごめん逆だった
.cpp
static const int TABLE[3]={1,2,3};
.h
extern const int TABLE[3];
.cpp
static const int TABLE[3]={1,2,3};
.h
extern const int TABLE[3];
689デフォルトの名無しさん
2023/11/28(火) 10:21:56.36ID:tbacT9e+ >>684
これは通るだろ? コンパイラは何よ?
これは通るだろ? コンパイラは何よ?
690はちみつ餃子 ◆8X2XSCHEME
2023/11/28(火) 10:25:57.66ID:mRTkdYl9 >>684
出来なかったというコードをそのまま提示して欲しい。
状況がよくわからないのに想像で対処法を考えてもしょうがない。
コードがちょっと長くなるなら
codetter とか wandbox とか ideone とかを使って。
出来なかったというコードをそのまま提示して欲しい。
状況がよくわからないのに想像で対処法を考えてもしょうがない。
コードがちょっと長くなるなら
codetter とか wandbox とか ideone とかを使って。
691デフォルトの名無しさん
2023/11/28(火) 10:27:57.27ID:vcMwjchf クラス内の定数を外部に生出しとかしないから
enunとかで宣言はするけど
何番目が欲しいとかはサービス関数作るしなぁ
enunとかで宣言はするけど
何番目が欲しいとかはサービス関数作るしなぁ
692デフォルトの名無しさん
2023/11/28(火) 10:30:15.59ID:vcMwjchf つか、static宣言の内部でしか使わないものを何でヘッダーファイルに書くの?
693デフォルトの名無しさん
2023/11/28(火) 10:32:49.40ID:vcMwjchf ヘッダーファイルはクラスコードの名刺みたいなもんで
外部にこう言う事が出来ますよってPRする為のファイルなんだから、普通は内部で完結してるものは書かないよ
外部にこう言う事が出来ますよってPRする為のファイルなんだから、普通は内部で完結してるものは書かないよ
694デフォルトの名無しさん
2023/11/28(火) 10:35:09.02ID:vcMwjchf マジックナンバー避ける為に#defineするとかも、cpp側の先頭に書くと、全ビルドしなくて済むしな
695デフォルトの名無しさん
2023/11/28(火) 11:07:40.67ID:t7+ip2Xg696デフォルトの名無しさん
2023/11/28(火) 11:35:51.07ID:vcMwjchf >>695
staticより「内部でしか使わない」って話の方を拾ってね
staticより「内部でしか使わない」って話の方を拾ってね
697デフォルトの名無しさん
2023/11/28(火) 12:43:41.53ID:dISnZSIc >>696
質問者は「クラス内からのみ参照する」って言ってただろ
質問者は「クラス内からのみ参照する」って言ってただろ
698デフォルトの名無しさん
2023/11/28(火) 18:17:05.00ID:vcMwjchf >>697
それならヘッダーファイルに書く必要無いやんけw
それならヘッダーファイルに書く必要無いやんけw
699デフォルトの名無しさん
2023/11/28(火) 18:50:50.78ID:dISnZSIc そら綺麗に一つのcppに全部そのクラスの実装を切り分けてるならcpp内にstaticでいいだろうけどね
700デフォルトの名無しさん
2023/11/28(火) 20:09:09.84ID:vcMwjchf そんな巨大なクラスは設計が間違ってないか?
701デフォルトの名無しさん
2023/11/28(火) 20:12:44.23ID:bqHRuT95 >>680
> 「ダブルポインタ」ってのも可笑しな使われ方してることが数多く観測される
それなw
初心者ほどこの用語を使ってるように見える
初心者が集まるところでこれを流布してるやつがおるんやろな
ポインタへのポインタっていうスケーラブルな定義が理解できてなくて
アスタリスクいっこのポインタと、二個のぽいんたがある!って感じなんやろな
> 「ダブルポインタ」ってのも可笑しな使われ方してることが数多く観測される
それなw
初心者ほどこの用語を使ってるように見える
初心者が集まるところでこれを流布してるやつがおるんやろな
ポインタへのポインタっていうスケーラブルな定義が理解できてなくて
アスタリスクいっこのポインタと、二個のぽいんたがある!って感じなんやろな
702はちみつ餃子 ◆8X2XSCHEME
2023/11/28(火) 20:20:10.37ID:mRTkdYl9703デフォルトの名無しさん
2023/11/28(火) 20:27:35.33ID:dISnZSIc >>700
巨大とかじゃなくて、あんたの考えてるであろう1ヘッダに1ソースってのも指針としてはもちろん良いんだけど(そして質問者のケースに合ってるならいいけど)
例えばクラステンプレートになると、ソースに実装を書けないからヘッダのどこか(ヘッダからインクルードしてユーザーに見え辛い場所には出来るが)で実装を書くことになる
そうなるとその実装からソースファイル内のstaticな値など見えるわけがないだろ
巨大とかじゃなくて、あんたの考えてるであろう1ヘッダに1ソースってのも指針としてはもちろん良いんだけど(そして質問者のケースに合ってるならいいけど)
例えばクラステンプレートになると、ソースに実装を書けないからヘッダのどこか(ヘッダからインクルードしてユーザーに見え辛い場所には出来るが)で実装を書くことになる
そうなるとその実装からソースファイル内のstaticな値など見えるわけがないだろ
704デフォルトの名無しさん
2023/11/28(火) 20:29:47.21ID:dISnZSIc >>702
もちろんそれもある
もちろんそれもある
705デフォルトの名無しさん
2023/11/28(火) 20:57:18.00ID:dISnZSIc まぁどれを選ぶかは本人の都合だけど、クラス定義の中にprivateで書くのが自然っちゃ自然な希ガス
706デフォルトの名無しさん
2023/11/28(火) 21:00:29.03ID:HOP5xTTo >例えばクラステンプレートになると、ソースに実装を書けないから
C++の設計ミスだな
特にテンプレ
C++の設計ミスだな
特にテンプレ
707デフォルトの名無しさん
2023/11/28(火) 21:55:43.79ID:vcMwjchf テンプレートは単なる#defineだからなぁ
あんなもん#defineでの置き換えによる副作用を引き起こす悪習の最たるもんだよ
あんなもん#defineでの置き換えによる副作用を引き起こす悪習の最たるもんだよ
708はちみつ餃子 ◆8X2XSCHEME
2023/11/28(火) 22:43:12.61ID:mRTkdYl9 一応はモジュールの概念の導入でちょっと良くなっているはずだが皆でこぞって移行するってほどには全然なってないからそこまで魅力的とは思われてないんやろね。
従来のスタイルと共存できるようにするのは C++ の立場では当然ではあるものの、悪い部分も捨てきれないことになりがち。
コンパイラのサポートもあまり熱心ではない(?)ような雰囲気だからそこも不安だし。
従来のスタイルと共存できるようにするのは C++ の立場では当然ではあるものの、悪い部分も捨てきれないことになりがち。
コンパイラのサポートもあまり熱心ではない(?)ような雰囲気だからそこも不安だし。
709デフォルトの名無しさん
2023/11/28(火) 23:00:59.77ID:5UazaCro どうも>>683です。
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;
}
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;
}
710デフォルトの名無しさん
2023/11/28(火) 23:06:12.31ID:5UazaCro 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に現れない上の書き方がいいと思いますが、これを最適としてよさそうですか。
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に現れない上の書き方がいいと思いますが、これを最適としてよさそうですか。
711デフォルトの名無しさん
2023/11/28(火) 23:19:21.29ID:dISnZSIc 解決おめ、自分の用途に合うと感じるならそれがベストと思うよ
712デフォルトの名無しさん
2023/11/29(水) 06:23:02.71ID:n75oaT1g h に static 描くと単に相互干渉しないってだけで
インスタンスは造られまくって無駄リソース出まくるんじゃね
インスタンスは造られまくって無駄リソース出まくるんじゃね
713デフォルトの名無しさん
2023/11/29(水) 09:24:39.36ID:5+1qDy8t 奴は人の書き込み見ちゃいないよw
714デフォルトの名無しさん
2023/11/30(木) 22:28:52.60ID:p6G1t8dm sizeof(クラス名)を活用できる場面はありますか。
メンバによってはCのsizeof(構造体名)と同じ使い方ができると思いますが、
クラス一般について考えると思いつきません。
たとえば
std::string name;
がメンバ変数にあるともう、クラスのサイズは不定になりそうです。
あっ、new は・・・いや、mallocと違ってサイズ指定は不要ですね。
メンバによってはCのsizeof(構造体名)と同じ使い方ができると思いますが、
クラス一般について考えると思いつきません。
たとえば
std::string name;
がメンバ変数にあるともう、クラスのサイズは不定になりそうです。
あっ、new は・・・いや、mallocと違ってサイズ指定は不要ですね。
715デフォルトの名無しさん
2023/11/30(木) 22:39:03.15ID:jq+Wc58z716はちみつ餃子 ◆8X2XSCHEME
2023/11/30(木) 23:39:52.07ID:3QI4e6Tt >>714
sizeof 演算子の適用結果は定数であることが保証される。
定数式として使うことができる。
std::string なども型の大きさが変動したりはしない。
C ではオペランドが VLA のときは sizeof の結果は定数にならないのだけれど C++ には VLA がないのでそういう例外はない。
(実際には処理系の拡張として VLA を使える場合もある。)
メモリアロケーションまわりを自分でコントロールする機会があれば普通のクラスの大きさを知る必要がある場合もなくはない。
それほど機会は多くないだろうけど。
本来 (?) の用途とは違うところで使われる場合もあって、
いわゆる SFINAE のトリックで sizeof が使われることもそれなりにある。
sizeof 演算子の適用結果は定数であることが保証される。
定数式として使うことができる。
std::string なども型の大きさが変動したりはしない。
C ではオペランドが VLA のときは sizeof の結果は定数にならないのだけれど C++ には VLA がないのでそういう例外はない。
(実際には処理系の拡張として VLA を使える場合もある。)
メモリアロケーションまわりを自分でコントロールする機会があれば普通のクラスの大きさを知る必要がある場合もなくはない。
それほど機会は多くないだろうけど。
本来 (?) の用途とは違うところで使われる場合もあって、
いわゆる SFINAE のトリックで sizeof が使われることもそれなりにある。
717デフォルトの名無しさん
2023/11/30(木) 23:55:15.59ID:p6G1t8dm >>716
高度な領域では使う場面はあるが、入門者には当分、なさそうですね。ありがとう。
高度な領域では使う場面はあるが、入門者には当分、なさそうですね。ありがとう。
718デフォルトの名無しさん
2023/12/01(金) 10:06:48.86ID:NZuUNSBe おまえら、stdとboostどう使い分けてる?
719デフォルトの名無しさん
2023/12/01(金) 13:58:15.55ID:aU4DjGEJ720デフォルトの名無しさん
2023/12/02(土) 07:29:47.55ID:qIqFVuKn まず鍵を与え、文字列を暗号化等して暗号文文字列を返したい。
暗号化ユーティリティ風のクラスをつくり、鍵とstringを渡す案 (1)と、stringを継承して鍵保持メンバ関数と暗号化メンバ関数を追加する案(2)を思いつきました。
どちらがでも実現できるように思いますが、何か設計のポイントはありますかね。
暗号化等には既製ライブラリ使います。
暗号化ユーティリティ風のクラスをつくり、鍵とstringを渡す案 (1)と、stringを継承して鍵保持メンバ関数と暗号化メンバ関数を追加する案(2)を思いつきました。
どちらがでも実現できるように思いますが、何か設計のポイントはありますかね。
暗号化等には既製ライブラリ使います。
721はちみつ餃子 ◆8X2XSCHEME
2023/12/02(土) 09:03:43.92ID:w8ZlbPjQ >>720
設計は総合的な判断だから単発の事情では判断しづらいというのは前置きとして書いておくけど、原則的には非メンバ関数として実装するほうがよい。
というよりも継承を使うほうが悪い。
「こういうメンバ関数があると便利」ということだけが理由なら継承を使うのは好ましくない。
プロジェクトの中で使う文字列を暗号化機能付きの文字列クラスで一貫して扱うならそれはそれでそんなに悪くないけど、通常は std::string 型のオブジェクトがあってそれを暗号化したいだけなのに別の型に変換にするという手間をかけるのがユーザーにとって便利だと思う?
設計は総合的な判断だから単発の事情では判断しづらいというのは前置きとして書いておくけど、原則的には非メンバ関数として実装するほうがよい。
というよりも継承を使うほうが悪い。
「こういうメンバ関数があると便利」ということだけが理由なら継承を使うのは好ましくない。
プロジェクトの中で使う文字列を暗号化機能付きの文字列クラスで一貫して扱うならそれはそれでそんなに悪くないけど、通常は std::string 型のオブジェクトがあってそれを暗号化したいだけなのに別の型に変換にするという手間をかけるのがユーザーにとって便利だと思う?
722はちみつ餃子 ◆8X2XSCHEME
2023/12/02(土) 11:45:21.73ID:w8ZlbPjQ 他の選択肢としてはストリームのアダプタにするとかいう方法も思いつく。
極端に大きなデータ (メモリに格納するには無理のある大きさ) にも対処したい場合は入出力と並行して処理することになるから、普通にストリームに書き出すのと同じように使ったら勝手に暗号化されてるというのは使う側としては楽でいい。
自分が使うものならそういう余計な抽象化層を挟むのは手間なだけかもしれないし、匙加減は微妙なところ。
極端に大きなデータ (メモリに格納するには無理のある大きさ) にも対処したい場合は入出力と並行して処理することになるから、普通にストリームに書き出すのと同じように使ったら勝手に暗号化されてるというのは使う側としては楽でいい。
自分が使うものならそういう余計な抽象化層を挟むのは手間なだけかもしれないし、匙加減は微妙なところ。
723デフォルトの名無しさん
2023/12/02(土) 12:16:48.61ID:0tC7Yjqi sqliteとかの(暗号化もあるけど)暗号化しないバージョンのDBを使ってて
書き込むとき勝手に暗号化してくれると有難いな
書き込むとき勝手に暗号化してくれると有難いな
724デフォルトの名無しさん
2023/12/02(土) 13:25:55.77ID:JgaBxQHi ここはプログラム技術板だぞ 自分で作れ
725デフォルトの名無しさん
2023/12/03(日) 06:49:36.39ID:xZHPSaOR このスレはC++の話ではない書き込みが多すぎる
726デフォルトの名無しさん
2023/12/03(日) 11:07:00.27ID:QTewqrs7 C++の守備範囲が広いんよ
727デフォルトの名無しさん
2023/12/03(日) 21:36:41.23ID:kkqQUehZ >>721
ありがとう。
非メンバ関数として実装、と見て最初はなぜ?と思いましたが、確かに文字列変換だけでクラスオブジェクトはいらないですね。
string 暗号化(鍵, 平文);
だけあれば十分だと。
ありがとう。
非メンバ関数として実装、と見て最初はなぜ?と思いましたが、確かに文字列変換だけでクラスオブジェクトはいらないですね。
string 暗号化(鍵, 平文);
だけあれば十分だと。
728デフォルトの名無しさん
2023/12/04(月) 21:09:04.65ID:wzr7hFvb msys2で開発環境を作りたくて
Windows10上にmsys2をインストールしてそのうえにpacmanからmingw-w64-x86_64-toolchainの最新版をインストールして
g++でコンパイルしてHello Worldを出力するところまではうまく行ったのですが
std::ifstream ifs("hoge.txt");
のような実行ファイルと同じ場所にある、あらかじめ用意したテキストファイルを読み込むだけのコードを書いてもファイルの読み込みに失敗します。
fstreamだけの問題ではなくfilesystemあたりをインクルードして適当な関数でテストしてもファイルが存在しないことになっていました。
どこで質問するのが適切なのかも見当がつかない状態なのですが原因に心当たりがある方がもしいらっしゃったら教えて頂けないでしょうか?
Windows10上にmsys2をインストールしてそのうえにpacmanからmingw-w64-x86_64-toolchainの最新版をインストールして
g++でコンパイルしてHello Worldを出力するところまではうまく行ったのですが
std::ifstream ifs("hoge.txt");
のような実行ファイルと同じ場所にある、あらかじめ用意したテキストファイルを読み込むだけのコードを書いてもファイルの読み込みに失敗します。
fstreamだけの問題ではなくfilesystemあたりをインクルードして適当な関数でテストしてもファイルが存在しないことになっていました。
どこで質問するのが適切なのかも見当がつかない状態なのですが原因に心当たりがある方がもしいらっしゃったら教えて頂けないでしょうか?
729デフォルトの名無しさん
2023/12/04(月) 22:11:21.42ID:+6ZMbPCa エラーメッセージは?
730はちみつ餃子 ◆8X2XSCHEME
2023/12/05(火) 00:16:37.88ID:z5PiblaY msys2 環境は数種類のモードがあるはずだがどれで起動した?
731デフォルトの名無しさん
2023/12/05(火) 04:57:07.09ID:DXGBHl1O 実行ファイルの場所がカレントになってないんだろ
getcwd()してみ
getcwd()してみ
732728
2023/12/12(火) 14:02:16.36ID:haJQSzRG エラーは何もなくて変数に何も格納されてない状態だったので原因よくわかりませんでしたが
今回は>>731さんの言う通りになっていて解決できました
まだmsys2自体の仕様も十分に理解してなくて手が回っていない状態なのでこれでいったん失礼します
ありがとうございました!
今回は>>731さんの言う通りになっていて解決できました
まだmsys2自体の仕様も十分に理解してなくて手が回っていない状態なのでこれでいったん失礼します
ありがとうございました!
733デフォルトの名無しさん
2023/12/12(火) 15:14:22.81ID:bMo3JLCK GUIから起動するとカレントディレクトリがホームになるんだったっけ?
734デフォルトの名無しさん
2023/12/13(水) 15:23:50.85ID:Xh1qTD5r OSの事情でカレントが簡単に移動してしまうのがめんどいな
735デフォルトの名無しさん
2023/12/13(水) 16:17:33.78ID:b3+IUHNQ プログラムの実行に必要な設定ファイルやデータファイルはカレントディレクトリではなく実行ファイルのパスを基準に決めたほうがいいね
736はちみつ餃子 ◆8X2XSCHEME
2023/12/13(水) 17:12:54.61ID:vPv7AHCs 設定ファイルの類いは AppData フォルダに置くのがこのましいということになってる。
アプリケーションインストール用のフォルダ Program Files は書き込み権限が制限されているからそこに設定ファイルは置けない。
逆にどうしてもアプリケーションと設定ファイルを同じフォルダに置きたいなら Program Files にはインストールできない。
Msys2 内で使うソフトならホームディレクトリ (windows のホームディレクトリではなく msys2 が設定するホームディレクトリ、環境変数 HOME で取得できる) に設定ファイルを置くのが基本的な習慣。
アプリケーションインストール用のフォルダ Program Files は書き込み権限が制限されているからそこに設定ファイルは置けない。
逆にどうしてもアプリケーションと設定ファイルを同じフォルダに置きたいなら Program Files にはインストールできない。
Msys2 内で使うソフトならホームディレクトリ (windows のホームディレクトリではなく msys2 が設定するホームディレクトリ、環境変数 HOME で取得できる) に設定ファイルを置くのが基本的な習慣。
737デフォルトの名無しさん
2023/12/13(水) 17:14:51.41ID:Xh1qTD5r 起動時の引数や 自分のフルパスを取得するAPI経由で
実行ファイルのある場所を基点にどうこうすることが多いわ (Windows
unix だと usr と bin で分ける文化があるからそういうのはどうなってるんやろか
起動時のカレントのまま?
実行ファイルのある場所を基点にどうこうすることが多いわ (Windows
unix だと usr と bin で分ける文化があるからそういうのはどうなってるんやろか
起動時のカレントのまま?
738デフォルトの名無しさん
2023/12/13(水) 17:20:10.83ID:b3+IUHNQ739デフォルトの名無しさん
2023/12/13(水) 17:23:03.86ID:HyXW4bJ5 カレントじゃ無くて、アプリが実行されたディレクトリに一緒に置いとくもんだろ?
ユーザー毎に違う設定にしたいなら、各ユーザーのホームディレクトリだろ?
ユーザー毎に違う設定にしたいなら、各ユーザーのホームディレクトリだろ?
740はちみつ餃子 ◆8X2XSCHEME
2023/12/13(水) 18:03:20.75ID:vPv7AHCs >>739
基本的にはそうだけどパッケージマネージャの管理方式との相性があったりする。
scoop で管理するなら設定ファイルも含めてひとつのフォルダに入れるほうが都合が良いと思う。
Msys2 内で pacman で管理するなら unix 風の流儀のほうが自然だし。
基本的にはそうだけどパッケージマネージャの管理方式との相性があったりする。
scoop で管理するなら設定ファイルも含めてひとつのフォルダに入れるほうが都合が良いと思う。
Msys2 内で pacman で管理するなら unix 風の流儀のほうが自然だし。
741デフォルトの名無しさん
2023/12/13(水) 23:12:49.25ID:zjCiNOvz グローバル位置に宣言したオブジェクトはmain前にコンストラクタが実行されますね。
仕様ではmain前に実行ということのほかに何か規定はありますか。
ある処理系で、main先頭である処理を呼び出すと成功するが、その処理を上記のコンストラクタから呼び出すと失敗するということがありました。
仕様ではmain前に実行ということのほかに何か規定はありますか。
ある処理系で、main先頭である処理を呼び出すと成功するが、その処理を上記のコンストラクタから呼び出すと失敗するということがありました。
742はちみつ餃子 ◆8X2XSCHEME
2023/12/14(木) 00:23:02.09ID:GWgG2Hfk >>741
ややこしい規則が色々あってここには書ききれないがおおざっぱにはこんな感じかな。
・ 定数初期化が終わってから動的初期化がされる
・ 動的初期化でも条件が揃ったときは静的初期化扱いで早めに初期化する最適化をしてもよい (しなくてもよい)
・ 翻訳単位内の初期化順序は定義が現れた順序
・ 翻訳単位をまたぐとどちらが先に初期化されるかは規定されていない
特に翻訳単位を跨いだら決まってないってのは引っかかりがちなポイントで、
強い依存関係のあるものはあまり細かく分割しないほうがやりやすいと思う。
ややこしい規則が色々あってここには書ききれないがおおざっぱにはこんな感じかな。
・ 定数初期化が終わってから動的初期化がされる
・ 動的初期化でも条件が揃ったときは静的初期化扱いで早めに初期化する最適化をしてもよい (しなくてもよい)
・ 翻訳単位内の初期化順序は定義が現れた順序
・ 翻訳単位をまたぐとどちらが先に初期化されるかは規定されていない
特に翻訳単位を跨いだら決まってないってのは引っかかりがちなポイントで、
強い依存関係のあるものはあまり細かく分割しないほうがやりやすいと思う。
743デフォルトの名無しさん
2023/12/14(木) 01:04:36.74ID:X6Ol8Z5z 普通は、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",
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",
744デフォルトの名無しさん
2023/12/31(日) 22:48:46.98ID:tpduSr4A 相談室から誘導されたのでこちらで
http://mevius.5ch.net/test/read.cgi/tech/1698705458/104
buf_にPODではないオブジェクトが含まれる可能性がある場合、この領域をどのようにcopyしたりmoveすればよいでしょうか?
http://mevius.5ch.net/test/read.cgi/tech/1698705458/104
buf_にPODではないオブジェクトが含まれる可能性がある場合、この領域をどのようにcopyしたりmoveすればよいでしょうか?
745デフォルトの名無しさん
2024/01/01(月) 01:29:30.25ID:/rCM9JK/ このスレッドはゼロからC++と言っているが、C言語を知っている前提になっているよなw
746デフォルトの名無しさん
2024/01/02(火) 11:00:49.80ID:TDOOgc4U ワシも割と長く底辺コピペプログラマだけどなんでそんな詳しくなれるの?ってなる
有能と俺みたいな無能はどこでプログラマの生き方をたがえたのか
有能と俺みたいな無能はどこでプログラマの生き方をたがえたのか
747デフォルトの名無しさん
2024/01/02(火) 20:21:16.21ID:G9bvfkvl748はちみつ餃子 ◆8X2XSCHEME
2024/01/02(火) 21:40:20.68ID:RkRzwbey 知識は入れないと増えないというすごく当たり前の話。
長く放置してたら勝手に増えるなんてことはないよ。
長く放置してたら勝手に増えるなんてことはないよ。
749デフォルトの名無しさん
2024/01/03(水) 08:18:02.54ID:3n4RUKo6 ガキの頃からマイコンBASICマガジン見てたけど
PCなかったしポケコンはあったからたまにあるポケコンゲームのソースをポチポチ入力してたけどそれで何かの知識になったか言われたら何にもならんかったな
PCなかったしポケコンはあったからたまにあるポケコンゲームのソースをポチポチ入力してたけどそれで何かの知識になったか言われたら何にもならんかったな
750デフォルトの名無しさん
2024/01/03(水) 08:26:31.48ID:uKn1SmuA 糞コテが
751デフォルトの名無しさん
2024/01/03(水) 13:07:46.32ID:3mJitcl/ >>749
SHARPのポケコンでマシン語使ってシューティングゲーム作ったけど?
SHARPのポケコンでマシン語使ってシューティングゲーム作ったけど?
752デフォルトの名無しさん
2024/01/03(水) 13:17:11.92ID:SgwYv7hO ポケコン触ってたころが一番楽しかったです
手の中に物理キーボードと実行環境があるんだもん
一生遊べるよ
手の中に物理キーボードと実行環境があるんだもん
一生遊べるよ
753デフォルトの名無しさん
2024/01/03(水) 14:56:53.56ID:giTORTIB >>744
memcpyでなくちゃんとplacement newでコピーorムーブコンストラクタ走らせればいんじゃね?
memcpyでなくちゃんとplacement newでコピーorムーブコンストラクタ走らせればいんじゃね?
754デフォルトの名無しさん
2024/01/10(水) 03:00:04.91ID:lNNg6PiH Class Hogeの中でたくさんのFugaを管理するために
std::vector<std::unique_ptr<Fuga>>というメンバ変数を作りました
可変長引数テンプレートで複数のstd::unique_ptr<Fuga>を受け取るコンストラクタを書こうとしたのですが
std::unique_ptrがコピー禁止のためうまくいきませんでした。
Hoge(Args&&... args)
という形で右辺値参照を受け取ってうまいことムーブしてClass Hogeを初期化する方法ってありますか?
std::vector<std::unique_ptr<Fuga>>というメンバ変数を作りました
可変長引数テンプレートで複数のstd::unique_ptr<Fuga>を受け取るコンストラクタを書こうとしたのですが
std::unique_ptrがコピー禁止のためうまくいきませんでした。
Hoge(Args&&... args)
という形で右辺値参照を受け取ってうまいことムーブしてClass Hogeを初期化する方法ってありますか?
755はちみつ餃子 ◆8X2XSCHEME
2024/01/10(水) 04:36:30.64ID:BOjhYgCx756デフォルトの名無しさん
2024/01/10(水) 11:27:22.10ID:lNNg6PiH >>755
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がコピー禁止でエラーになったのでムーブにしたいけど書き方がわかりませんでした。
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がコピー禁止でエラーになったのでムーブにしたいけど書き方がわかりませんでした。
757はちみつ餃子 ◆8X2XSCHEME
2024/01/10(水) 12:45:18.04ID:BOjhYgCx >>756
この場合は 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));
}
この場合は 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));
}
758デフォルトの名無しさん
2024/01/12(金) 09:52:36.06ID:Umd8uX9b c++で日本語の連想配列ってあります??
759デフォルトの名無しさん
2024/01/14(日) 15:30:33.22ID:O4q5V5KL >>758
std::mapじゃだめなん?
std::mapじゃだめなん?
760デフォルトの名無しさん
2024/01/16(火) 21:37:05.24ID:eUaXJLuy >>757
無事に動作させることができました。ありがとうございます!
無事に動作させることができました。ありがとうございます!
761デフォルトの名無しさん
2024/01/20(土) 18:17:15.80ID:9qysS+ur 時間のかかる処理があり、それが現在のスレッドをブロックして欲しくないので
その処理の部分に関してstd::async()の利用を検討していますが、
これって戻り値(future 型)でモニターしないといけない感じですか?
上記の処理はいつ終わるかは気にしないので別スレッドに投げっぱなし?で構わない
のですが... pthread_detach()的な?
その処理の部分に関してstd::async()の利用を検討していますが、
これって戻り値(future 型)でモニターしないといけない感じですか?
上記の処理はいつ終わるかは気にしないので別スレッドに投げっぱなし?で構わない
のですが... pthread_detach()的な?
762はちみつ餃子 ◆8X2XSCHEME
2024/01/21(日) 12:43:25.73ID:4rk7TZPC >>761
std::thread のメンバ関数に detach はあるけど、期待するのはこういうこと?
ただ、メインスレッドが終了すれば他のスレッドが稼働中でもプロセス終了処理に入るし、
プロセス終了処理の中で標準ライブラリの後始末している最中に他のスレッドが
標準ライブラリを使うようなことがあると破綻するかもしれない。
強引に終わらせて良いなら std::quick_exit で即死させるという方法も取れるが、
基本的にはプログラムを終わらせるときには全てのスレッドを終了させて (終了を待って) おくのが
普通だと思う。
std::thread のメンバ関数に detach はあるけど、期待するのはこういうこと?
ただ、メインスレッドが終了すれば他のスレッドが稼働中でもプロセス終了処理に入るし、
プロセス終了処理の中で標準ライブラリの後始末している最中に他のスレッドが
標準ライブラリを使うようなことがあると破綻するかもしれない。
強引に終わらせて良いなら std::quick_exit で即死させるという方法も取れるが、
基本的にはプログラムを終わらせるときには全てのスレッドを終了させて (終了を待って) おくのが
普通だと思う。
763デフォルトの名無しさん
2024/01/21(日) 21:48:26.38ID:zlvjOB5M >>761ですが、お返事ありがとうございます。
はい、とりあえず thread::detach() を使うようにしました。1つの疑問は、
https://ja.cppreference.com/w/cpp/thread/future/~future によると
> ただし、その共有状態が std::async によって作成され、まだ準備完了になっておらず、これがその共有状態への最後の参照である場合は、ブロックする可能性があります。
ええ何それ、というのが発端でした(後出し失礼)。
確かに、メインスレッドの終了時のこともありますし、スレッドの後始末をちゃんと
した方が本当はいいように思われます。処理が長時間たっても終了しない場合
タイムアウトさせたりとかも。
何かシステマティックな方法等あるでしょうか。参考になるものがあれば...
はい、とりあえず thread::detach() を使うようにしました。1つの疑問は、
https://ja.cppreference.com/w/cpp/thread/future/~future によると
> ただし、その共有状態が std::async によって作成され、まだ準備完了になっておらず、これがその共有状態への最後の参照である場合は、ブロックする可能性があります。
ええ何それ、というのが発端でした(後出し失礼)。
確かに、メインスレッドの終了時のこともありますし、スレッドの後始末をちゃんと
した方が本当はいいように思われます。処理が長時間たっても終了しない場合
タイムアウトさせたりとかも。
何かシステマティックな方法等あるでしょうか。参考になるものがあれば...
764はちみつ餃子 ◆8X2XSCHEME
2024/01/22(月) 12:54:36.50ID:T1sqP3ZB >>763
メインスレッドの終了直前でまずは適当にフラグを立てた上で他のスレッドの終了まで待機する。
重い処理をしているスレッドの側で完了ではないにしても区切り良く終われるポイントでフラグを読んで
フラグが立っていれば後始末ルートに入ってスレッドを終了させる。
その結果としてメインスレッドの待機状態が終わってプロセスの終了。
というのが普通の大まかな流れだと思う。
その上で待機時間があまり長すぎるようだと強引にでも終わらせるとかの処理を入れるかも。
std::async は既存の関数を非同期化するちょっとしたユーティリティという立場なんじゃないかな。
それで事足りるときは便利で簡単だけど、細かい制御を勝手にやってくれるわけでもないし、
やろうとするとちょっとイマイチって感じ。
メインスレッドの終了直前でまずは適当にフラグを立てた上で他のスレッドの終了まで待機する。
重い処理をしているスレッドの側で完了ではないにしても区切り良く終われるポイントでフラグを読んで
フラグが立っていれば後始末ルートに入ってスレッドを終了させる。
その結果としてメインスレッドの待機状態が終わってプロセスの終了。
というのが普通の大まかな流れだと思う。
その上で待機時間があまり長すぎるようだと強引にでも終わらせるとかの処理を入れるかも。
std::async は既存の関数を非同期化するちょっとしたユーティリティという立場なんじゃないかな。
それで事足りるときは便利で簡単だけど、細かい制御を勝手にやってくれるわけでもないし、
やろうとするとちょっとイマイチって感じ。
765デフォルトの名無しさん
2024/01/28(日) 11:52:43.80ID:W0uCnQb3 質問なのですがどんな環境(ロケール設定)の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()が上書きしないように見えるのですがそういうもの?
数値や時刻の入出力を修飾無し(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()が上書きしないように見えるのですがそういうもの?
766はちみつ餃子 ◆8X2XSCHEME
2024/01/28(日) 13:12:39.75ID:hRRbWEE/ >>765
言語仕様通りならそれらの関数を呼び出さないようにすれば環境に固有の表現の変換はしない。
std::setlocale の設定が C の標準関数の挙動に影響するのはその通り。
ただし、様々な環境での「同じ動作」を期待するなら "C" を与えるべき。
空の文字列を渡した場合には環境に固有の設定であり、通常はシステムの設定が反映される。
プログラムは起動したときに setlocale(LC_ALL, "C"); 相当の状態なので、普通は書く必要もない。
std::locale::global での設定は C++ の標準ライブラリの挙動に影響するだけでなく std::setlocale での設定にも反映されるので両方を呼び出す必要はない。
これもプログラム起動時のロケール設定は "C" 相当になっているのでそれで良ければ呼び出す必要もない。
ただし、 std::locale::global に与える設定が名前を持たない場合 (つまり std::locale("") のような場合) は std::setlocale 相当の変更もするかどうかは規定されない。
imbue はストリームにロケールを結びつけるのでグローバル設定とは独立して機能する。
言語仕様通りならそれらの関数を呼び出さないようにすれば環境に固有の表現の変換はしない。
std::setlocale の設定が C の標準関数の挙動に影響するのはその通り。
ただし、様々な環境での「同じ動作」を期待するなら "C" を与えるべき。
空の文字列を渡した場合には環境に固有の設定であり、通常はシステムの設定が反映される。
プログラムは起動したときに setlocale(LC_ALL, "C"); 相当の状態なので、普通は書く必要もない。
std::locale::global での設定は C++ の標準ライブラリの挙動に影響するだけでなく std::setlocale での設定にも反映されるので両方を呼び出す必要はない。
これもプログラム起動時のロケール設定は "C" 相当になっているのでそれで良ければ呼び出す必要もない。
ただし、 std::locale::global に与える設定が名前を持たない場合 (つまり std::locale("") のような場合) は std::setlocale 相当の変更もするかどうかは規定されない。
imbue はストリームにロケールを結びつけるのでグローバル設定とは独立して機能する。
767デフォルトの名無しさん
2024/01/28(日) 14:11:55.68ID:eBJAlicu クラスオブジェクトの代入文に、=による単純コピーと、=演算子関数による独自コピーのどちらを使うか迷います。
たとえばメンバ変数が基本データ型の集まりなら単純コピーでいい。
今出くわしたのはメンバ変数がstd::array<int, 3>の場合で、まあたぶん単純コピーでよさそう?じゃあstd::vector<myclass>なら?などと疑問が深まります。
あとコピーコンストラクタによる初期化も合わせて考える必要がありそう。
たとえばメンバ変数が基本データ型の集まりなら単純コピーでいい。
今出くわしたのはメンバ変数がstd::array<int, 3>の場合で、まあたぶん単純コピーでよさそう?じゃあstd::vector<myclass>なら?などと疑問が深まります。
あとコピーコンストラクタによる初期化も合わせて考える必要がありそう。
768はちみつ餃子 ◆8X2XSCHEME
2024/01/28(日) 14:36:51.31ID:hRRbWEE/769デフォルトの名無しさん
2024/01/28(日) 15:36:35.20ID:W0uCnQb3 >>766
レス㌧クス、
>ただし、様々な環境での「同じ動作」を期待するなら "C" を与えるべき。
なるほど "C" ですたか、これか↓
https://www.ibm.com/docs/ja/zos/2.2.0?topic=utility-locale-naming-conventions
>普通は書く必要もない。
実はウィンドーズでUnicodeで出力する場合限定かもですだが、ロケール設定しないままだと
日本語OSでも漢字が表示されなかったり(L"Hello World! 漢字" → 表示: Hello World! )
英語OSに持っていったら L"Hello World! 漢字" が丸ごと出なかったり……orz
まあ漢字はこの際どうでも良いので、ロケール設定 "C" で行こうと思いまつ
レス㌧クス、
>ただし、様々な環境での「同じ動作」を期待するなら "C" を与えるべき。
なるほど "C" ですたか、これか↓
https://www.ibm.com/docs/ja/zos/2.2.0?topic=utility-locale-naming-conventions
>普通は書く必要もない。
実はウィンドーズでUnicodeで出力する場合限定かもですだが、ロケール設定しないままだと
日本語OSでも漢字が表示されなかったり(L"Hello World! 漢字" → 表示: Hello World! )
英語OSに持っていったら L"Hello World! 漢字" が丸ごと出なかったり……orz
まあ漢字はこの際どうでも良いので、ロケール設定 "C" で行こうと思いまつ
770デフォルトの名無しさん
2024/01/28(日) 16:37:46.15ID:eBJAlicu >>768
そうです。
そうです。
771はちみつ餃子 ◆8X2XSCHEME
2024/01/28(日) 16:38:46.52ID:hRRbWEE/772はちみつ餃子 ◆8X2XSCHEME
2024/01/28(日) 16:52:54.16ID:hRRbWEE/ >>770
デフォルトで生成される代入演算子は全てのサブオブジェクト (基底とデータメンバ) を
代入演算子でコピーするのと同じ挙動になることになってる。
基底やデータメンバが適切に代入演算子を定義されているのならデフォルト生成にまかせてよいことが多い。
注意を払う必要がある典型的なものは生ポインタで、
ポインタをコピーしても指してる先のオブジェクトはひとつだから
そのへんの扱いはデフォルト生成だとあかんことになる。
あとは外部のリソースと結びついているオブジェクトだと単純にコピーできないか、コピーさせないこともあるな。
分かりやすい例で言うなら std::thread なんかはスレッドを抽象化したものだけど
オブジェクトをコピーしたらスレッドもぽんぽん増えるなんてことになっても困るし
スレッドひとつに対応しているオブジェクトがいくつもあるようでも困るのでコピーできないようになってる。
それぞれに事情があるので明瞭な判断基準があるわけじゃないけど、
デフォルト生成の結果がほんまに自分の意図通りに動作するか考えてみて
あかんなら自分で書くしかない。
デフォルトで生成される代入演算子は全てのサブオブジェクト (基底とデータメンバ) を
代入演算子でコピーするのと同じ挙動になることになってる。
基底やデータメンバが適切に代入演算子を定義されているのならデフォルト生成にまかせてよいことが多い。
注意を払う必要がある典型的なものは生ポインタで、
ポインタをコピーしても指してる先のオブジェクトはひとつだから
そのへんの扱いはデフォルト生成だとあかんことになる。
あとは外部のリソースと結びついているオブジェクトだと単純にコピーできないか、コピーさせないこともあるな。
分かりやすい例で言うなら std::thread なんかはスレッドを抽象化したものだけど
オブジェクトをコピーしたらスレッドもぽんぽん増えるなんてことになっても困るし
スレッドひとつに対応しているオブジェクトがいくつもあるようでも困るのでコピーできないようになってる。
それぞれに事情があるので明瞭な判断基準があるわけじゃないけど、
デフォルト生成の結果がほんまに自分の意図通りに動作するか考えてみて
あかんなら自分で書くしかない。
773デフォルトの名無しさん
2024/01/28(日) 17:03:17.17ID:eBJAlicu >>772
いつもありがとうございます。
たいていはデフォルトでよさそうですね。
std::vectorは可変長配列ってことなので、<int>であってもデフォルトでいいのかなと心配に…あこれはvectorのほうで独自=定義されてるなら問題ないわけですね。
いつもありがとうございます。
たいていはデフォルトでよさそうですね。
std::vectorは可変長配列ってことなので、<int>であってもデフォルトでいいのかなと心配に…あこれはvectorのほうで独自=定義されてるなら問題ないわけですね。
774デフォルトの名無しさん
2024/01/30(火) 20:47:22.29ID:RcbbllHt 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
}
#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
}
775はちみつ餃子 ◆8X2XSCHEME
2024/02/02(金) 00:09:46.55ID:BQKaaqcl >>774
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
}
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
}
776デフォルトの名無しさん
2024/02/02(金) 11:28:24.45ID:xohFoxUO >>775
横からだけども
> X x2 = 2; // b:NG(conversion from 'int' to non-scalar type 'X' requested)
って
X x2(2);
と同義じゃねーの?
横からだけども
> X x2 = 2; // b:NG(conversion from 'int' to non-scalar type 'X' requested)
って
X x2(2);
と同義じゃねーの?
777はちみつ餃子 ◆8X2XSCHEME
2024/02/02(金) 12:19:41.13ID:BQKaaqcl >>776
違うよ。
C++ では引数ひとつのコンストラクタは変換コンストラクタとして「も」使うことになっているから
違う文脈でも結果的に同じコンストラクタが呼び出されることになるけど
構文糖というわけではなくて違う解釈を経ている。
違うよ。
C++ では引数ひとつのコンストラクタは変換コンストラクタとして「も」使うことになっているから
違う文脈でも結果的に同じコンストラクタが呼び出されることになるけど
構文糖というわけではなくて違う解釈を経ている。
778デフォルトの名無しさん
2024/02/02(金) 12:28:48.56ID:xohFoxUO 細かいなぁ
779はちみつ餃子 ◆8X2XSCHEME
2024/02/02(金) 18:32:30.30ID:ZFQgO+dm 動くなら同義と考えても大した問題じゃないが、
ここでは実際に結果が違う (一方はエラーになる) ことの説明だから……
ここでは実際に結果が違う (一方はエラーになる) ことの説明だから……
780デフォルトの名無しさん
2024/02/02(金) 22:30:30.14ID:d8Flt8Cn これはなぜエラーになるのですか。
std::string s = "abc";
char name[10] = s.c_str();
error: array must be initialized with a brace-enclosed initializer
次と同等とみなせないのはなぜ?
char name[10] = "abc";
std::string s = "abc";
char name[10] = s.c_str();
error: array must be initialized with a brace-enclosed initializer
次と同等とみなせないのはなぜ?
char name[10] = "abc";
781774
2024/02/03(土) 05:00:19.85ID:vGyzbOvf >>775 774だけどありがとう。暗黙だと変換が途中で途切れるかもなのか。
一番通って欲しいのがbなんだけど難しいっすね…
一番通って欲しいのがbなんだけど難しいっすね…
782デフォルトの名無しさん
2024/02/03(土) 05:21:33.46ID:4Ieoi/Xm >>780
c_str()が返すのはchar*
char name[10] = "abc"; は特別扱いで char name[10] = {'a', 'b', 'c', 0}; と同じ
cの時からある雀の涙猫の額ばかりの文字列サポート
c_str()が返すのはchar*
char name[10] = "abc"; は特別扱いで char name[10] = {'a', 'b', 'c', 0}; と同じ
cの時からある雀の涙猫の額ばかりの文字列サポート
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 日本行き空路49万件キャンセル 中国自粛呼びかけ 日本行きチケット予約の約32%に相当 ★4 [ぐれ★]
- 中国の局長は「両手をポケット」で対峙 宣伝戦で国民に示す ★3 [蚤の市★]
- 【音楽】Perfume・あ~ちゃんの結婚相手「一般男性」は吉田カバンの社長・吉田幸裕氏(41) 高身長で山本耕史似 [Ailuropoda melanoleuca★]
- 【大分】佐賀関で大規模火災、170棟以上が延焼中 70代男性1人と連絡取れず [ぐれ★]
- 【サッカー】U-17日本代表、激闘PK戦制す 北朝鮮撃破で6大会ぶり8強入り U17W杯 [久太郎★]
- 「クマはなるべく山に返す努力を」「クマと戦争は間違っている」動物保護活動家の主張 棲み分けと学習放獣でクマ被害なくなるのか?★7 [ぐれ★]
- とらせん IPあり
- 巨専】
- こいせん 全レス転載禁止
- 【DAZN】ワールドカップ欧州予選総合 ★5
- 侍ジャパンシリーズ2025「日本vs韓国」その12
- 【ATP】テニス総合実況スレ2025 Part 211【WTA】
- アンケート調査で「高市発言は問題なし」 93.5%wwwwwwwwwwwwwwwwwwwwwwwww [279254606]
- 自閉症が「んなっしょい」と連呼するお🏡
- 【悲報】大分市佐賀関の火事、20軒→170軒に延焼🔥 [481941988]
- 両手でフレミングの法則やってくれ [577451214]
- 日本人の海外旅行したきのマナーよくなったのはいつから
- へそグリグリ
