C++相談室 part161
■ このスレッドは過去ログ倉庫に格納されています
=std::numeric_limits<decltype(ほんそれ)>::max() condition_variableってなんでわざわざmutexと一緒に定義しないといけないの面倒でしかたないんだけど。
しかもへんてこな目覚めがあるなんてバグを平然と放置してるし。
win32のSetEvent()のほうが俄然使いやすいんだけど。 mutex は排他の仕組みであって同期の仕組みと分離する思想なんじゃないかなぁ……。
あんまりイケてないとは思うけど。 それはOSの問題なうえ、充分合理的な動作と認められている。 へんてこな目覚めはなんで生じるのかは知らんなんか深い理由でもあるんじゃないのJK
それはおくとして、両者にはキューイングの思想の違いがまずありき、
[1] WindowsのSetEvent()はイベント発生をキューイングし、待機中スレッドをキューイングしない
[2] 条件変数はイベント発生をキューイングせず、待機中スレッドをキューイングする
これでかなりイベント発生と待機の組み合わせの性格の違いが出る。
[1]は待機中スレッドが無くともイベントをセットでき、その後最初に待ちに入ったスレッド1個が待ち解除される
[2]は待機中スレッドが無いとイベントが無視されるが、通知方法をnotify_one()だけでなくnotify_all()も選べる
[1]はWaitForMultipleObject()により1箇所の待機で複数種類のイベントを待ち受けられる(μITRONのイベントフラグ的な使い方ができる
が、[2]でそれをやろうとするとあるイベントでスレッドを起こしたら、そのスレッドの待機中スレッドとしてのキューイングを
他のイベントついてもクリアせねばならない、みたいな余計な処理が必要で効率的に実装できない
ということは、条件変数でWaitForMultipleObject()的なことをやろうとしたら、イベント要因を別途変数にセットして
待機中スレッドに伝える必要があり、この変数の操作→イベント待ち解除→解除されたスレッドが変数を参照、
というのをatomicにやらざるおえないから、ミューテックスのブロック内でイベントの待機とセットを行わねばならない仕様に、
なったと思う それ隠蔽できるだろうけど、条件変数の基本要素がそれなんだからそういうもんです。 しかしまあ普通にスレッドの中にイベント待ちを作ったら、
イベント要因は
(1) 本来のイベントの意味(複数かもしれん
(2) スレッド終了
の2種類は必ず生じるけどこのために2種類以上のイベントオブジェクトを設けてWaitForMultipleObject()で待機するのは
アフォらしいので結局条件変数的に、イベントオブジェクトは1個、イベント要因を表す変数が1個、みたいな形になって
条件変数と同じようなしくみに落ち着く
、希ガス
(ただしイベントオブジェクトとイベントを待つスレッドの実体が完全に1対1ならミューテックスによるガードは不要 mutexないとあっちのスレッドが条件変えちゃうのでは イベント要因が3種類以上とかイベント発生と待機解除が必ず1対1でなければならない、みたいなケースを含むちょう一般論で言うとそうかorz >>388
>イベントオブジェクトは1個、イベント要因を表す変数が1個
その方がめんどくせえわ >>383
condition_variableの引数にmutexのロックがあるおかげで休眠処理を(1-1)〜(1-5)のようにできる
(1-1)mutexでロックして、(1-2)起動条件を設定して、(1-3)起動条件のチェックをしてから、(1-4)休眠して、(1-5)ロックを解除
もしそういう仕組みが無いとこんな感じになるかな
(2-1)mutexでロックして、(2-2)起動条件を設定して、(2-3)ロックを解除して、(2-4)起動条件のチェックをしてから、(2-5)休眠する
休眠を起こす方は、(1)mutexでロックして、(2)起動条件を設定して、(3)起動して、(4)ロックを解除、となるわけだけど、
(2-1)〜(2-5)の場合、(2-4)の後(2-5)の前に(1)〜(4)が動くことができて、その場合に永遠に休眠する場合がある
(1-1)〜(1-5)ならそういう問題が無い バトン持ってるやつが偉いというのはいいとして、バトンを途切れなく渡すための仕組みが要るんじゃ >>383
実際まあ面倒くさいよな。
最近は後で書き直すつもりでとりあえずスピンしてatomic_bool待つコード書いてしまってるわ >>388
>>392
ご回答ありがとうございます。
かなりお詳しい方とお見受けします。
ご回答いただいてから、何回も読み直してしますが
いまいち理解できていない状況です。
そういうものとして、コーディングすれば別に支支障はないのですが、御二方のように完璧に理解したいと勉強しております。
また質問させて頂くかもしれませんが、その際はよろしくお願い申し上げます。
以上 基底クラスのprivateメンバと、private継承された基底クラスのpublicメンバって派生クラスから見たら同じじゃないんでしょうか?
前者は派生クラスからアクセス不可で、後者は派生クラスからアクセス可能なようです
というとこは意味が違うんでしょうが調べでもよく分かりませんでした
どなたか教えてください public/privateは、自分よりも外側からのアクセスを許可するかの指定。
class B{
private: int b1;
public: int b2;
};
class C: private B{};
int main(){
B b;
C c;
}
b.b2はアクセス可能。c.b2はアクセス不可能。
class C内からは元々publicだったthis->b2のアクセスに制限はない。 >>397
class Bをprivate継承したことで、b2はclass Cのprivateメンバになるということですね
理解しました、ありがとうございました >>398
需要なさそうなC++の派生みたい。
人気が出てきたらスレを分けよう。 通常のキャストと参照へのキャストの違いを教えてください。
#include <iostream>
class Base {};
class Derived : public Base {};
int main()
{
Derived d;
Base& b1 = static_cast<Base&>(d); //@
Base& b2 = static_cast<Base>(d); //A
}
このようなとき、@だとコンパイルOK、Aだとコンパイルエラーになります。
どのような違いがあるのでしょうか? >>401
キャストが原因でコンパイルエラーが出てるわけではないです
簡単に言うと②の右辺は rvalue なので非 const lvalue に束縛できません >>401
値へのキャストは、一時オブジェクトを作り必要ならコンストラクタを実行する
参照へのキャストは、一時オブジェクトを作らない
ただしconst修飾された参照と右辺値参照の場合はこの限りでない 具体例で言うとこれ↓はアリってこと。
#include <iostream>
class Base {};
class Derived : public Base {};
int main()
{
Derived d;
Base&& b3 = static_cast<Base>(d);
const Base& b4 = static_cast<Base>(d);
}
注意点として、
本来なら一時オブジェクトは式の終わりに解体されるので参照が無効になりそうなもんだが
参照で受けている場合はその参照の寿命と同じ分だけ延命される特例がある。 俺が言ったのはこれのこと
struct base
{
base(int);
};
int main()
{
static_cast<base const&>(1);
static_cast<base&&>(1);
} コンストラクタの最適化(によるコンストラクタ呼び出し自体を削除)は
コピコンだけが適用? じゃあ>>406 のコードでは
コンストラクタの呼び出しだけは保証されて、
その後のコピーやムーブは保証されない動きになる? そもそも406のコードにコピーもムーブも一つも出てきてないけど ・フリーランスに立ちはだかる「常駐」の壁。慣例を打ち壊し、
“テレワーク”案件3割→8割へと成長を遂げた「クラウドテック」の軌跡
・リモートワーク求人専門サイト「プロリモート」がリニューアルオープン、
業務委託契約の求職者と企業をマッチング
・1/3以上が採用につながる高マッチング率、リモートワーク×エンジニア・デザイナー専門の
人材紹介サービス「ReworkerAgent」正式リリース場所からも時間からも自由な働き方を実現!
・『ReWorks(リワークス)』リモートワーク特化型転職サイトとして 3月5日 リニューアル
・副業・兼業マッチングサービス「クラウドリンクス」登録者数2万人突破
中小企業で進む副業人材の採用、96%が継続採用を希望
・フリーランスが活用できる「最大1,000〜3,000万円・補助率50%〜75%」の
『ものづくり・商業・サービス補助金』とは?概要や条件を解説
・茨城県日立市、県外からの「テレワーク移住者」に最大151万円の助成金
・長野市、市内に移転・事業所設置し、移住することで最大550万円の支援金を支給 練習でオブジェクトデータベースもどき を書いたらGITHUBに送ったのになんか反映されない。
がーん!! コンストラクタって本当に戻り値無いんですか?
例えば
MyClass c = MyClass();
としたとき、cにはMyClassのコンストラクタで生成されたインスタンスが格納されます
戻り値が無いのになぜそうなるのでしょうか? >>414
それは明示的な型変換 (関数記法) という規則で示されている。
https://timsong-cpp.github.io/cppwp/n3337/expr.type.conv
見かけ上は普通の関数呼出しと区別がつかない記法を使うけれど関数呼出しではない。
クラス名を関数風に使ったらコンストラクタで構築したオブジェクトを (あたかも関数の返却値のように) 返すことになっているというだけなんで、
まあそういう仕様なのだと覚えてもらうしかしょうがない。
コンストラクタは特別な地位にあって色々と特別な規則があるんよ。 >>415
ありがとうございます
そういう仕様だと覚えることにします
ついでで申し訳ないんですが、コンストラクタと明示的な型変換って同じものなんですか?
MyClassA a;
MyClassB b = MyClassB(a);
としたとき、コンストラクタはMyClassBの関数ですが、明示的な型変換はa(MyClassA)の関数ですよね? >>416
> コンストラクタと明示的な型変換って同じものなんですか?
違う。 明示的な型変換を試みた結果としてコンストラクタが呼び出されたりもするということ。
> コンストラクタはMyClassBの関数ですが
MyClassB のメンバ関数の意かな?
> 明示的な型変換はa(MyClassA)の関数ですよね?
何がいいたいのかわからない。
MyClassB と書いてあるのに何故か MyClassA のなんらかのメンバ関数が呼ばれると思っているということ?
どうしてそう思ったのかもうちょっと詳しく説明してみて。 >> 417
class MyClassB {};
class MyClassA
{
public:
operator MyClassB() const {
return MyClassB();
}
};
int main()
{
MyClassA a;
MyClassB b = MyClassB(a);
}
このようなとき、型変換で呼ばれるのはMyClassAのメンバ関数であるoperator MyClassBですよね?
MyClassBのメンバ関数であるコンストラクタを呼び出しているのと見分けがつかないので、疑問に思いました explicit指定してなけらば代入はコンストラクタに渡される >>418
ユーザー定義変換演算子があればそれが使われたりもすることもある。
どの状況で何が呼ばれるのかは複雑な解決規則があって、どちらかが優先になることもあれば曖昧 (エラー) になることもある。
この場合にどうなってるのか仕様を辿ってみたんだが、
MyClassB(a) は C スタイルのキャストと等しいので (MyClassB)a と同等、
そしてこれは static_cast<MyClassB>(a) と同等と解釈される。
このとき MyClassB temp(a) と宣言したときのように初期化された架空の変数 temp の値が返される。
そういうルールだった。
MyClassB temp(a) と宣言したときに MyClassB が MyClassA を受け取るコンストラクタを持っていれば
それが呼ばれる (この場合はそのようなコンストラクタはないので呼ばれない) し、
そうでないなら暗黙の型変換が実施されるので MyClassA::operator MyClassB が呼ばれてから初期化される。 職業としてc++を使用してる人に聞きたいんだけど
設計者がどう動作するか分かってないコードが含まれる製品が出荷されてるのっておかしくない?
しかもその担当は、俺あんまりパソコン得意じゃないって。
そんな人間が書いてるソフトをお金を出して買ってくださってるお客様に言えるかよ、馬鹿なのかな まあ売る方も買う方も承知でやってる互助会みたいな世界もあるから 自社製品のすべてをわかっている事業者なんてないよ
もしものためにお客様相談窓口あるわけだし >>423
そう言うことではない。
では、あなたに聞きたい
車を買いに行って、ディーラーの人に「このボタンなんですか?」と質問して「押してみないと分からない」なんて答えたらどう思いますか?
ディーラーが設計してるわけではないことくらい誰でも知ってるけど、ここで買っていいのか?って思いませんか? >>421
C++使いはPCのパワーユーザーとは限らんよ
それにPCだって無数の技術が詰め込まれていて
たとえるなら1つの大学のようなもので
迂闊に「俺はものすごくPCに詳しいんだ!」なんて言うと
ほぼ100%恥かくしな >>424
外部仕様と内部仕様の区別もつかないボンクラ乙w つかC++関係無くね
どの工程にでも言える話をここでされても困るんだけど まず>>421がC++との関連を示すべき。それ以外のところで話を広げても不毛。 >>420
解決規則が知りたいと思ったのですが状況によって難しそうですね
混乱してきたので整理して考え直します
ありがとうございました >>428
マジで言ってるならもう少し勉強してきた方がいい
ボタンの操作とかのように取説に載ってるのは外部仕様
>>421はそういう話じゃない
原理はわからなくてもテストちゃんとしとけばいいという世界もある windows作ってる開発者や営業にメモ帳のショートカット全部言えるか聞いてみればいいんじゃね?
外部仕様すら知らんの?馬鹿なのかなって 「メモ帳のショートカットを言え」がなんのことやらわからない。 最大限にエスパー能力を発揮してアクロバティックに解釈するとテキスト形式のファイルのことではないかと思う。
デフォルトだとメモ帳に関連付けられているからテキスト=メモ帳という認識が出来上がる可能性はある。 関連付けされた拡張子の話をしてるのかな?
それでもあとからインストールされたものでコロコロ変わるから、意味不明だな。 メモ帳はnotepad.exe、ショートカットはキーボードショートカットの意味だがそれすら想像つかないなんてずいぶん頭が悪いな
パソコン得意じゃないのはお前のことじゃん >>436
Windowsのショートカットはそういう意味じゃない。 >>438
そんなのわかっているが、彼の略語が自分にしかわからないから問題にしている。 >>438
メモ帳にショートカットキーは割り当てられていない。
メモ帳を起動する方法の種類を言っているんだろう。 自分のPCの設定をデフォルト設定だと思っているジジイだろうな 争いが起きるのは霊的な問題もあると思うんですよね。
先日亡くなられた安倍元総理も生前大切にされていた霊験あらたかな壺があるそうなんですよ。
ただ、とても値が張るそうで、安いものでも3000万を下らないそうなんです。
そこで、5ch有志でお金を出し合って共同で購入しませんか?
そうすればスレも安定すると思うんです。 Windowsのファイルの種類のひとつが「ショートカット」というのがわからなくなって、Windowsそのもののことがわからないのに知ったかぶりで物を言う認知症のじいさんなんだろ。 おまえら全員Windows板行って二度と帰ってくんな >>432
そらで全部言える必要ないだろ
開発者なら外部仕様にアクセスできるだろうから一覧くれって言えば出すことはできるだろ メモ帳にショートカットキーがあるという架空の設定で話していてもよくわからない。 F5で現在時刻入力とかCtrl+Gで行番号指定ジャンプとかCtrl+-/+/0で縮小・拡大・元に戻すとかの
メモ帳のキーバインドのことなんじゃないのどうでもいいけど >>449
メモ帳そのもののことを言っていたわけか。メモ帳を使っている人間がどれだけいるのか疑問だけど。 というか、あれってエディットコントロールの機能ですよね
エディットコントロールのソースってどっかでみることが出来ますかね? Windows のソースコードは一部の政府機関や学術機関と契約を結んで提供している事例はあるが、
個人で見せてもらえるようなもんじゃないよ。
あえて言うなら ReactOS (Windows 互換の OS を目指すオープンソースプロジェクト) が参考になるかもね。 >>415
MyClass a();
MyClass & b = MyClass();
const MyClass & c = MyClass();
MyClass d = MyClass(); ← コピーコンストラクタ発動?
それともムーブ? >>421
javascriptやelectronやphpやvb/vbaの方が判ってない人が描いてる確率は高い >>449
最近覚えたのは Win+G ですね判ります >>449-450
ああそれで
「押してみないと判らない」
って話が出て来たのか
普通の人間なら闇雲に押すんじゃなくて
押す前にマニュアルやヘルプファイル読むだろうな GUIでキー操作というのは矛盾も含んでいるんだけどな >>454
基本的にはムーブコンストラクタが呼ばれる場面なんだけど……。
一定の条件でコピーやムーブを省略 (Copy elision) してよい場合がある。
MyClass d = MyClass();
はその条件にあてはまるので
MyClass d();
と同じ挙動になることがある。 (コピーもムーブも起こらない。)
省略が許される場合の一部が C++17 以降では省略が必須に変更された。
また、 C++17 以降で省略が必須のときはコピーコンストラクタもムーブコンストラクタも存在しなくてよい。
故に以下↓のような例は C++14 ではエラーだが C++17 では通る。
struct MyClass {
MyClass(const MyClass &) = delete;
MyClass(void) = default;
};
int main(void){
MyClass d = MyClass();
} むかしまだMacOSが漢字TalkだったころにMacキチガイの知りあいが
「Windowsなんて駄目だよ、だいたいマウスにボタンが2つあるみたいなシンプルさを欠く設計な上に
なにかとキーボードを併用しないといけない、GUIとして未完成といわざるをえない(キリッ」とかいいながら
Macでマウスボタンとコマンドキーやらシフトキーのコンビネーションをものすごい熟練の手付きで操作していたのが印象的だった windows10でスタートメニューを非表示にしたいのですが良い方法ないですかね?
スタートメニューのHandleを取れれば良いのですが、、。
ネットでいろいろ調べましたが見つけたサンプルコードは、windows10では動きませんでした。 以下のプログラムを実行したとき、変数xとyが初期化されるのはどういう理屈ですか?
class myClass
{
public:
int x;
int y;
};
int main()
{
myClass c{ 100, 200 };
}
暗黙のコンストラクタで代入されているのかと思いましたが、
xとyをprivateにするとコンパイルエラーになるので違うようです。
インスタンス生成の{}を()に変えるとコンパイルできなくなるのでそれもどうしてか知りたいです。 struct myClass
{
int x;
int y;
};
int main()
{
struct myClass c = { 100, 200 };
}
と同じ理屈じゃね? C言語からやってないと構造体の初期化は理解出来んだろうな trivial ctorじゃ説明つかないからなaggregateは 建増しでやってきた言語だからしょうがないけど初期化の方法がやたらいっぱいあって混乱する >>465
集成体初期化 (Aggregate Initilization) に該当する。
クラスが一定の条件を満たしたときに集成体の扱いになる。
文法表記を似せているだけの別物と思った方がいいかも。
ちなみに C++20 からは丸括弧でも集成体初期化が出来るようになってるよ。 >>466-467, >>471
ありがとうございます
C言語の構造体の初期化と同じですね
後方互換を保つために残してるような気がしました
コンストラクタ定義が無いときしか使えないんですね 皆さんにお聞きしたいんですけど
inline展開しまくることによる弊害って主になんでしょうか? もうデメリットはなくなって来たな
実際のコンパイラもデフォでinlineぽい動きするし
ただの開いたサブルーチンというだけでなく定義の統合がありがたい デバッグが面倒臭くならない?
そうだあれか
リバエンし難くする効果があるとか インライン展開するとスタックトレースで関数名が出なくなりますか? >>478
コンパイラにもよると思うけど
おそらく出なくなると思います! ■ このスレッドは過去ログ倉庫に格納されています