◎正当な理由による書き込みの削除について: 生島英之とみられる方へ:
C++相談室 part158 YouTube動画>1本 ->画像>3枚
動画、画像抽出 ||
この掲示板へ
類似スレ
掲示板一覧 人気スレ 動画人気順
このスレへの固定リンク: http://5chb.net/r/tech/1636969758/
ヒント:5chスレのurlに http://xxxx.5chb.net/xxxx のようにbを入れるだけでここでスレ保存、閲覧できます。
Windows10でrecursive_directory_iterator使うと全角ファイル名が化けまくるんだけど
これwstringバージョンないよね
使い物にならないってこと?
>>4 Windows でファイルシステムを操作するなら、もう utf16/W 系を陽に使うしかないのでは
http://2chb.net/r/tech/1434079972/53 なんにも確認してないがrecursive_directory_iteratorはpath扱うだけのはずで
wstring云々いいだすのがもう怪しい
wstringなら解決すると思ってる時点で頭可笑しい
全世界の文字集めたらWORDじゃ足りないことくらいアメ公でなければすぐわかりそうだが
>>11 でも、ハングル文字は、28文字しかないのに 5000ポイントも使っていたり、
元々文字じゃなかった絵文字を勝手に文字の様に扱ったりして行って
肥大化しただけで、世界の文字自体はそんなに多くない。
ユニコードの文字の扱い方に問題が有るんだと思う。
>>12 ハングルは、子音、母音、パッチムは、それぞれ20〜30程度しかないが、
それを組み合わせて1文字に組み立てられているらしくて、組み合わせ爆発で、
1万1000文字を越える。
全ての組み合わせが使われているわけではない。
また、実際に使用される文字は2500文字ほどらしい。
表意文字である漢字は、どうしようもないが、単なる表音文字に過ぎない
ハングルに、Unicodeは、1万1000ポイント以上を割り当ててしまってる。
しかし、漢字も滅多に使わない文字を含めても1万5000文字くらいで、
アラビア文字も28文字くらいしかないそうだから、世界で使われている
本当の文字は、恐らく、4万文字もあれば足りるはず。
ユニコードが16BITで表しきれない以上に厄介なのは、UTF8で表現した時に、
50文字しかないひらがなまで 3バイトになっていること。
カタカナまであわせても100程度しかないのに。
さすがに、アメリカ人の傲慢さを感じざるを得ない。
こんな文字コードを一生使い続けると考えるとうんざりするので、
多分、これが終わりではないだろう。
むしろ、これで終わりにしてはならない。
[追加]
ユニコードの文字数が多い点に関して:
・16BITで表現できない文字の大部分は絵文字。
・数学記号などは数学を扱う時に必須なのに、重要な数学記号が沢山不足している。
つまり、非常に使用頻度が高い記号が含まれてない。
・逆にどうでもいいような変な遊びの記号などが大量に入っている。
別にそれはグラフィックで書けばいいのに。
数学記号などは文書の中でも使えるし、学問的にも昔から良く使われているのに
なぜかユニコードには含まれてないものが沢山ある。
それに、呼び方や起源は同じでても、数学的には異なる意味を持つコードが1つに
割り当てられていたり、πが四角く表示されて、数学では絶対に使わないグリフ
になってしまっていたりする。
基礎的な数学まで知らないばかが考えたとしか思えないし、それが
何十年間も改善されてない。
ユニコードは欠陥コード。
>>14 円周率の意味での「パイ」(PI)は、数学では必ず小文字で、かつ、丸みを帯びた
おなじみの記号を使い、決して、門構えのようなπは使わないし、
数学の本では見た事が無い。しかし、ユニコードではそれが標準になっており、
誰が使うのという感じがする。
もう一つは、φの記号。物理学で、磁束を表すのは、くるっと回るφ。
数学の空集合のファイは、ドーナツに棒を貫通させたようなグリフ。
しかし、ユニコードでは両者の区別が訳が分からないことになっていて、
困る。
あとは、⇔の記号が、横方向はあるが、縦方向が無いらしいこと。
これは最悪。
空集合記号とギリシャ文字のファイを混同してるような無知に文句つけられてUnicodeも大変だな
ΦφФфΦɸØø∅⌀
Φ
Φ
Φ
φ
φ
φ
ϕ
ϕ
そもそもが世界中の言語の発展は場当たり的な習慣の積み重ねを何千・何万年と続けてきてグダグダなんだから
それをどうがんばって整理しようとしたところでグダグダなんだわ。
元からグダグダだったのが Unicode のグダグダさとしても表れてきただけ。
言語ごと作り直しでもしない限り綺麗な符号体系にならないんで、
グダグダさと折り合いをつけてつきあっていくしかしょうがない。
>>16 Unicodeではちゃんと区別されて無いだろ。
>>18 数学の空集合の記号とは違ってる。
どうせ、パイ(π)は四角い変なグリフで、数学では絶対使えない。
>>21 Greek PhiはU+03A6(大文字)・U+03C6(小文字)・U+03D5(数学用シンボル)
Empty setはU+2205
全く別のコードポイントが割り当てられてるし、
>>19の資料でも全く別の文字として議論されてるけど
何を見て何がどう区別されてないと思った?
unicodeで一番困るのがソート
単純にコードの大小でソートするとおかしな事になるからな
>>25 調べてみたが、そもそもグリフが安定していないから数学では使えない。
数学ではグリフによって意味を分けているから。
そもそも、数学では縦棒が斜めになっているか、縦になっているかでもニュアンス
が違うことがある。
特に空集合の場合、斜めになっていないと、普通の数学的な感覚には
合わない。完全に垂直だと駄目だ。
それに、イタリック体と普通のプレインな書体も、明確に区別できるようになって
ないと、プログラムの本でも使えない。
たとえば、BNFなんかでもそう。
遊びでグリフを変えてもらっては使い物にならない。
後は、カンマの横幅を勝手に狭くするのはプログラマー泣かせ。
カンマは飾りじゃなくて、あるのと無いのとでは大違いだし、
ピリオドと完全に区別できなくてはならないのに、狭すぎて連続した
場合に、フォントが小さい時、非常に判別しにくいことがある。
フォントを作る人は大学以降の数学や物理学に詳しい人に絶対に
聞いて欲しい。
Appleのスティーブジョブスのせいで、プロポーショナルフォントが多くなり。
それをIDEなんかでも使う馬鹿(=MSのプログラマ)がいて、もうアホかと。
空白は有るのかないのか分からないし、からの「〜」が、上の方にある
チルド~に見えたり、カンマは狭すぎていくつあるのか数えられない、
円周率のπは、数学では決して使うことのない門構えのようなグリフだし。
遊びで変えるな。
芸術ではないんだ、厳密に区別しないといけないんだ、プログラムも
数学も。
それはUnicodeじゃなくてフォントの問題なのでは
コードポイントとグリフとフォントの区別すらついてない無知蒙昧丸出しで
よくもまあそんな意味のない長文を恥ずかしげもなくグダグダ書き散らかせるもんだ
その度胸だけは褒めたるから、Unicodeに物申す前に基礎から勉強しろよ
>芸術ではないんだ、厳密に区別しないといけないんだ、プログラムも
>数学も。
フォントとグリフと書体をこちゃ混ぜにしてる人間がこれ書いてんのギャグだなw
ユニコードを内包する世界最大の文字集合がGB18030。
漏れが書いたように思われそうだがちげう
記念パピコ
>>36 ハングルを3000文字くらいと、コンポジションに落とし込めなかったのは人類史における、、、まーいーや終わったことだ。
まぁMacでファイル名読むと「パ」が「ハ」と「゜」に割れてマジビビったけどな。
>>27 Unicode は言語情報を保持しない。
いわゆる中華フォント問題が起こるのはテキストだけからは日本語フォントを適用すべきなのか
中国語フォント (あるいは他の言語) を適用すべきなのかわからないからで、
そのあたりはアプリケーションレイヤで解決する想定になっている。
文字の形が重要なアプリケーションでそれができてないなら単にアプリケーションがカスってだけ。
ギリシャ文字のパイと数学記号のパイも個別に符号を割り当てるべきではないが、
Unicode は既存の文字コードを統合することという要件が現実問題として有るために
既存の文字コードで区別している例があると区別せざるを得ない。
文字コードとしての理想の姿と、
まずは皆が Unicode という規格に載ってこないと理想もクソもねぇという板挟みがある。
答えは相手が握ってるので俺がただしいなどありえない
Unicodeとか文字とグリフの区別がぐちゃぐちゃになりつつあるとい
う印象、ど
うしてこうなった?!
>>41 いや、円周率を、パイという記号で表すのは中学生でも知っている訳で、
あのおなじみの形状が安定して表示できない段階で文字コードとして終わってる。
文字数の制約があるならまだしも、誰も使わないような漢字や、その場しのぎの
ふざけた記号が大量に含まれているのに、円周率という誰でも知っていて
記号が絶対にあの記号で無ければ伝わらないものに対して、ちゃんとした
記号が安定したコードポイントにはどこにも割り当てられてないのは
大問題。
中国語の文字と日本語の文字の違いよりも影響はずっと大きい。
いいかげんにしろよ
・見た目を決めるのはフォントの仕事であってUnicodeのコードポイント割り当てに文句付けるのはお門違い
・そもそも数学記号用のコードポイントはギリシャ文字とは別にちゃんと割り当てられてる(Mathematical Alphanumeric Symbols)
・ここはC++スレだスレ違い消えろお前の巣はこれだ→
http://2chb.net/r/tech/1593777227/ >>46 実際にはちゃんと割り当てられてない。
しかも、フォントの仕事である、と切り分けるのも問題。
というのは、現実に、円周率としては決して使っては成らない
おかしなフォントがパイの自に割り当てられていて、それを回避する方法が
ない。なので、まともなパイのフォントを自作するか、画像ファイルを
用意して画像を挿入するしか方法が無い。
>>47 他の文字コードならそれが回避できるとでもいうんけ?
あほか。
>>48 まず、円周率の記号は、ギリシャ文字のパイならなんでもいいというわけではないこと
を文字コードやフォントを作ってる人が理解することから始めなければならない。
また、数学で同値記号で使う矢印は矢印だったら何でも良いという訳ではなく、
左右と上下の区別と、二重線か一重線かという好みの問題も含めて、
固定的なフォントでなくてはならない。二重線の場合、中は白抜きでなくては
ならないので、決して塗りつぶすべきではない。
そういうことを理解してない人が文字コードやフォントを作る資格はないのに、
アメリカ人はそれをやってしまってる。アメリカ人は何もかもおかしい。
クラフトマンシップが無い。
>>49 アメリカ人が悪いわけではない、数学者を文字コード制定に加えなかった馬鹿どもがアメリカ人の中にもいる、というだけ、それがどのような属性の人間か容易に推測できるだろう?
というか、TeX をそのまま持ってこればいいだけの話なのにそれすらわからないのは、どういったわけなんだ?
>>49 知らんがな。
それはアプリケーションで解決しろと言ってる。
>>50 あなたは、物を知らない。
TeXも実はあまり綺麗ではないし、日本で標準に使われていた数学記号を表示しにくい。
最初、同値記号が長すぎたり、左右方向しかないことにまず、つまずき易い。
回避作が全く無いわけではないが。
近似的に等しいの記号も、日本で馴染みのある上下に点々を打つものは表示しにくい
とかもあるし。
円周率のパイと空集合はさすがに表示できるが。
日本人が作っていたソフトには、良いソフトが多かった。
アメリカ人がそれを潰した。
というか、日本人が日本製のソフトを買わない。
例え良いソフトがあっても。
わけが分からん。
>>52 ≒ \risingdotseq \fallingdotseq
⇔ \Leftrightarrow
上下方向同値は、なければないでなんとかなるのでは?
数学数学うるさいくせにいつまでも用語使いがいい加減なままなのはどういうわけだ
そろそろ文字・記号・文字コード・コードポイント・グリフ・フォント・書体の定義くらい理解して使い分けろよ
>>55 グリフとフォントの違いはいくら調べても、あまり分からなかった。
コードポイントは分かる。
しかし、コードポイントに単にギリシャ文字の「パイ」を割り当てていても、
円周率用におなじみのパイであるとは限らず、実際にWindowsでは、門構え
のような変な文字になってしまってる。
そして、それを回避するのは難しい。
字体と字形は違うという話もある。
漢字の場合は確かにそうかもしれない。
しかし、数学では最後の形が重要だから、最後の最後の最後の画面上に表示される
グラフィックが、数学の習慣にぴったり一致してなければ駄目。
円周率にギリシャ文字のπを充てた数学が悪い、数学は俺々円周率記号を作るべきだった
って言ってる?
auto \u03c0 = std::numbers::pi;
コードは別れてるのだから、あとはデザイナの問題、フォント使用者の問題だろ
外人が作ったフォントの"ゐ"の字が"い"と同じだったからunicodeに"ゐ"の字を安定的に出せるようにしろっていうのはお門違い
お前らおっぱいの形で何を興奮してるんだ?w
この変態どもめw
おっぱいに興奮するのは正常な性欲で変態じゃないぞ
あ、変態から見るとノーマルが変態なのかw
うちのπは変換選択中は数学記号のπで一覧に出てるんだが変換確定すると門構えのπになるなω
アプリのフォントとIME(FEP)のフォントが違うんだろうなωωω
秀丸なら数学用のπだし
メモ帳だと門構えのπだったわ
TeX使ったらどうでもよくなるけど
とりあえず
メイリオは糞π
MS Gothic は 数学用π
MS 明朝は 数学用π
みかちゃん ぎりぎりセーフ
Migu 1M 数学用π
IPAex Gothic 数学用π
IPAex 明朝 数学用π
んーいまのところだめなのメイリオだけだなω
56はwindowsがって言ってんだから全部ダメなんだろ
using namespace std;
するのとstd名前空間内の各エンティティについて
using std::foo;
するのに違いはありますか?
はい。前者は std 内全部の名前が修飾なしで使えるようになりますが、後者は指定したものだけになります。
明朝体とかゴシック体がフォント
明朝体で書かれた「あ」とゴシック体で書かれた「あ」は異なるグリフの「あ」
文字としては同じ
ということのはずだがユニコードはぐちゃらけてしま
tったど
うしてこなうった!?
ググったらJISで「♯」と「#」が異なる文字だからユニコードでも元に戻せるように異なるコードにしているとか
ワケワカメ
一昔前の似たような文字を同じコードにする方針な美しいユニコードはどこいった……?!
>>71 シャープとナンバーサインは違う記号で違う意味でしょ。
カタカナの「ロ」と漢字の「口」まで統合されかかったというエピソードもあるんだが、
そういうのが Unicode の美しさだと思うか?
何を以て「似たような文字」とするか文字に対する考え方というのは
それぞれの文化によるによるので既に確立している符号体系を尊重するのは合理的な方針なんだよ。
歴史的経緯を切り捨てられないのは不格好だが逆に言えば既存の不格好さを継承する程度で済む。
そうだよスレ違いのUnicode叩きも擁護も出て行け
♯include は動かない方が良い
\ も mac だとやばい \ があるらしいなω
codepadだかideoneだかが
\nを勝手に半角の¥nにしてコンパイル通らなくて可笑しいときがある
>>77 素人丸出しだからそのへんでやめとけ
\が(過去の経緯で)本来あるべきグリフで表示されないのはwindows(日本語設定時のみ)のほう
JIS X 0201 (7ビット及び8ビットの情報交換用符号化文字集合) による。
JIS X 3010 (プログラミング言語C) の中でもスラッシュとチルダが JIS X 0201 では円記号とオーバーラインに
置き換えられる旨の補足情報が書かれている。
つまり Windows の挙動は日本の (文字コードに関する) 規格を尊重した結果だし、C の JIS 規格でもちゃんと言及している。
とはいえ ISO/IEC 9899 に反する事情があるからこそ日本の規格 (JIS) にするにあたって補足を入れる必要があったわけで、
「本来あるべき」から遠いのは確かに Windows のほうとは言える。
>>79 知ってると思うが
これの話なんだが
http://codepad.org/WsmFWVty #include <stdio.h>
int main()
{
printf("abc\n");
return 0;
}
WindowsのvisualC++2019でDLLのロードが出来ません
dll defからlibをつくり#pragma comment( lib, "sample" )とやればできた記憶なんですが
64bitのバージョンも全部合わせてあるんですが
10年ぶりにやったら動きません
ボーランドC++だと修飾名が変わってdefを書き換えたりはあったと思うのですが
> error LNK2019: 未解決の外部シンボル sqlite3_open
自己解決しました
dumpbin.exe /exports コマンドでdefファイルを作成した場合、
EXPORTS の記述がなかったからでした
>>81 エスケープを円で覚えてるからそんな間抜けな間違いするんだよ
ブログラマならエディタの設定変えとけ
ナニナニ
彡⌒ ミ ナニナニ
(´・ω・`) 彡⌒ミ
,彡⌒ 彡⌒ ミ (・ω・`) また文字コードの話?
(´・ω(´・ω・`) ⌒ ミノ⌒ミ
u_| ̄ ̄||´・ω・`)ω・`) マター?
/旦|――||// /|と ノ
| ̄ ̄ ̄ ̄ ̄| ̄| . |-u
|_____|三|/
>>90 プログラマ=ハゲと思われるからそのAAやめろよ(´・ω・`)
実際C++プログラマはハゲが多いんだから別にいいだろう
教祖からしてハゲなんだし
Greek PhiはU+03A6(大文字)・U+03C6(小文字)・U+03D5(数学用シンボル)
Empty setはU+2205
全く別のコードポイントが割り当てられてるし、
>>19の資料でも全く別の文字として議論されてるけど
何を見て何がどう区別されてないと思った?
プログラミング言語の世代論というのがあって、
第一世代は CPU のアーキテクチャべったりの機械語、
第二世代は機械語が解る人間向きの低級言語、
第三世代は自然言語寄りの高級言語、
第四世代は目的型言語、
…… で、いわゆる「第五世代」は、コンピュータの都合じゃなくて
人間の都合に合わせようよ、というコンセプトになった。
「じゃあ、どのあたりから始めるか」という話は
ありそうに思う。
>>79 素人丸出しとか言ってるが
実際macだと設定によってはバックスラッシュと同じ扱いにならない\が
普通にキー叩いたら出るんだぞ
普段からU+005Cのグリフがバックスラッシュになってるフォントしか使わないから円記号に違和感しかない
そりゃ個人の自由だけどプログラミングしてるなら少しフォントにこだわってもいいと思う
日時を数値に変換する良い感じの関数教えてくださいよ
おどろき最小の法則と言えば
https://onihusube.hatenaぶろぐ.com/entry/2020/04/03/211442
人を下に見られる程精通してる人って正直羨ましいわ
知れば知るほどまだまだ知らない事が沢山あるなぁと勉強不足を実感してしまう
↓
知らないから人をバカに出来るんだよなー
↑
むしろ人を下にみないと精神状態が不安定なんでしょ
Windows App SDK入れてみたがエラーが多くまだ使えない
ヘッダファイルで変数の宣言するとき、引数付きのコンストラクタ使おうとするとコンパイルエラー出るんですけどこの書き方って良くないんですか?
>>105 ヘッダだからエラー、というわけではないです
ヘッダじゃない普通の cpp に書いてもエラーなのでは?
具体的にソースを示してください
>>106 // NG ヘッダにそのまま書こうとすると型指定子が必要ですとエラーが出る
private:
MenberLibClasse obj ("piyopiyo");
// OK ヘッダには引数なしで宣言した後、cppでobjをメンバに持つクラスのコンストラクタの初期化子リストを使うと何故か通る
private:
MenberLibClasse obj;
Class() :obj ("piyopiyo") { }
挙動把握しきれないんですけどライブラリ側の問題でしょうか??
>>107 NG のときのエラーの内容は?
エラーメッセージを貼ってください、正直、よくわかりません
>>107 宣言の位置でメンバを初期化できるのはC++11からだけど、それが原因かな?
書くとしたらこうやろ
private:
MenberLibClasse obj = "piyopiyo";
型指定子が必要って言われるのは
関数宣言と見られていて
仮引数の場所にリテラルがあるってことだ
>>111 イコールはダメで波括弧に変えたらコンパイルできました
private:
MenberLibClasse obj{"piyopiyo"};
>>99 using namespace std::chrono;
// 現在時刻を取得
system_clock::time_point tp = system_clock::now();
// 現在時刻のミリ秒部分を取得
auto msec = duration_cast<milliseconds>(tp.time_since_epoch()).count() % 1000;
みたいなことをやると良い最後のまmillisecondでもsecondでもnanosecondでも逝ける
こないだ死ぬほどやり倒すた、
しかしずんねんながら現状MSVCのstd::chrono::zoned_timeが未実装のため、
システム時刻関連処理についてstd::chronoの利用を断念すた、orz
なおtime_point同士で引き算もできる
結果を具体的時間単位の時間表現にするのは同じくduration_cast<T>()
ostringstream の precision の上限がなぜか 255 に設定されているようで
mpreal big("1000桁規模の浮動小数点数");
ostringstream ss;
ss.precision(1000);
ss << big;
とすると ss に 255 文字程度しか入らないのです
cout.precision(1000);
cout << big;
だと 1000桁出ます
ostringstream の precision の上限をもっと大きくする方法はありますか?
とりあえず判ったのは
ss.rdbuf() の default の上限値が 255 らしい
>>115 >MSVCのstd::chrono::zoned_timeが未実装
TZ=JST-9
とか描いてあってもだめかな
>>120 ss.rdbuf()->in_avail()
再現しそうな最小限のコードだけ描いて
mingw + gcc でコンパイル&実行したら期待通りの動作をしたが
VC だとやっぱり上限があるっぽい動きになってる
rdbuf() 使いつつ seek() すれば大丈夫かも知れないが
自分の使い方が間違ってるだけだと思いたい
とりあえず mpreal は関係なかった
VC 側の問題らしいのでもう少し掘ってみる
VC 側 rdbuf()->pubseekpos() 併用で解決
クラスのメンバ変数が全部intとかdoubleとかで足し算掛け算ができるものの場合に、
クラスの足し算掛け算を各メンバ変数の足し算掛け算として定義したいのですが
operator +とかoperator *のオーバーロードでメンバ変数について一個ずつ書いていく以外の方法ありますか?
今やろうとしていることでメンバ変数が多いので、いちいち列挙せずに済むなら便利だなと思ったのですが
>>117 VC の in_avail() が間違った値を返してるんだなこれ
>>126 現在の C++ はリフレクション系の機能が弱くてクラスからデータメンバを列挙するというようなことは出来ない。
「全てのメンバに対してやってくれ」というようなことはできない。
ただ、対象となるメンバを取り出すものさえ用意すればそれを様々な演算に適用することは可能だと思う。
つまり、メンバの列挙を一度で済ませる (なんども列挙しなくてよい) ことは出来るかもしれないってことね。
とはいえそれはそれで割とクソめんどうくせぇメタプログラミングの下準備が要るので
いっそ列挙しまくったほうが簡単かもしれん。
>>121 駄目なんじゃないかと思う
std::chronoはtime_pointを抽象化してタイムゾーンの異なる時刻間の差分を自動で取り扱いたい(そういう思想な)はずで、
ということはローカルタイムを扱う手段としてzoned_timeは無くてはならないピースとみなさざるおえない
どうしてもというならstd::chrono::system_timeを経由して古き良きtime_tとtime_pointの相互変換ができるから、
time_tまで降りてローカルタイムにしてtime_pointに戻す手はあるが、それをすると
同じtime_pointクラスで表される2種類のシリアル時間がプログラム内に生じてしまうから、
std::chronoの上記思想(時刻の差分や比較を自動で安全に取り扱いたい)が破壊される
ライブラリ仕様の理想が高邁すぎるか実装側の怠慢によって大事な用途において糞ライブラリになってしまっている例
何が出来ないと言っているのかまるで分からん
出来る部分と出来ない部分の切り分けがいるんでないの?
time_point(事実上UTC)とローカルタイムの相互変換がstd::chronoが思想的に目指しているほど安全にはできない
zoned_timeが実装されない限り
time_point(事実上UTC)同士の比較や差分はzoned_timeが実装されてないバージョンでも安全にできる
えっと、
>>135はUTCとローカルタイムの変換ってわかります?
std::chronoで現在時刻を取得する一番自然な方法は、
system_clock::time_point now = system_clock::now();
や
他にもtime_tからの変換という方法があるが、いまさらtime_t使え言うぐらいならstd::chrono使わずにtime_tだけ使うは;;;
で、nowはどう見てもUTCであるから、日本時間を知りたければ、
上記time_point nowが日本時間の何年何月何日の何時何分何秒なのかを出力できねばならない
std::chronoの中にはzoned_timeを使わずにそれをやる手段が見当たらない
C++20より前のchronoはタイムゾーンのこと知らんからな…
>>99で聞かれてるのは「日時を数値に変換」だろ?
前提も条件も全部曖昧で、自然とか思想とか思い込みばかり
何を使うと何が出来て何が出来ないを全く説明してない
chronoはローカルタイムを扱えない、と言ってると思うよ
ローカル時刻かUTCか以前の問題として、そもそもどんなフォーマットで数値に変換するのか
それが不明だったから誰も回答しなかったのだろうに
あとドキュメント信じる限りじゃzoned_timeはVS2019 16.10から使えるってよ
C++は糞
std::は糞ばかり
boost最強
まで読んだ
「良い感じの関数」なんて今流行りwのAIとか使わんと無理でしょ
確かにchronoは今一だね
filesystemはthread, iomanipとの連携が悪すぎ
使いにくいったらありゃしない
- filesystemは
+ tilesystemや
auto p = (void*)[]{};
これが通らないんだけど
stateless-lambdaは関数と見なせない?
auto p = (void*)(void (*)())[]{};
auto p = []()->void*{};
もう少し学習しろ
何がしたいんか知らんけど
auto p = [](){};
auto p = []()->void*{};
auto p = []()->void{};
本人の意図が判らんことには絶対に正解に辿り着けない質問大杉
void func1(void*);
void func2(){}
func1(func2);
のようなことをしようとしてて怒られるから
func1((void*)func2);
にしてた
で、func2で名前空間を汚染したくないから
stateless-lambda使おうと思った
関数 (関数ポインタ) を void* で受ける雑なことをしといて名前空間を汚すのは気にするのか。
まあフレームワークとかの側でそうなってたら仕方ない場合もあるけど……。
variant的なことを昔ながらの方法でやっているのかもしれない
auto p = []()->void*{return NULL;};
↑これはOKだが
auto p = []()->void*{};
↑こっちはコンパイルエラーにして欲しいよね
単にステートレスラムダを関数ポインタに変換したいならこういう有名なハックがある
auto p = +[]{};
ポインタに単項プラスなんぞ考えたこともなかった
void test(char* p)
{
cout << +p << endl;
cout << *+p << endl;
cout << *(0+p) << endl;
cout << 0[p] << endl;
}
C++11 や C++17 や C++20 とかどのオプションでコンパイルされているかを
コンパイル中に判断したいのですが
ソースコード中にどう書けばよいのですか
>>161 #include <iostream>
#include <cstdio>
int main() {
int a[] = {1, 2, 3, 4};
std::printf("%p %p\n", &a, &a + 1);
std::printf("%p %p\n", +a, +a + 1);
int (*p)[4] = &a;
std::printf("%p %p\n", p, p + 1);
int *q = &a[0];
std::printf("%p %p\n", q, q + 1);
return 0;
}
0x7ffd548f5d00 0x7ffd548f5d10
0x7ffd548f5d00 0x7ffd548f5d04
0x7ffd548f5d00 0x7ffd548f5d10
0x7ffd548f5d00 0x7ffd548f5d04
つまり&a[0]と書くのを+aと書くだけですませられる
どっちが分かりやすいかはさておき
__cplusplus マクロ見るんじゃね?普通は
あとは言語機能ごとのマクロ見たり
>>165 <iostream>いらないね
それとlvalue transformationがかかる場面で
わざわざ単項プラスを使う必要性が
そのサンプルでは示せてないようだが
>>166 処理系がちゃんとそのへんのルールを守ってくれればいいが現実は非情である。
The following macro names shall be defined by the implementation:
__cplusplus
The name __cplusplus is defined to the value 199711L when compiling a C++ translation unit.
G++ now sets the predefined macro __cplusplus to the correct value, 199711L for C++98/03, and 201103L for C++11.
http://gcc.gnu.org/gcc-4.7/changes.html But g++ < 4.7.0 is __cplusplus defined alway 1.
https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ C++でblas, lapackを使うのにいいインターフェースってどれでしょうか?
調べてたらCppLapack, Lapack++、armadillo とか出てきましたが、定番さとか使いやすさとか教えていただけると嬉しいです
とりあえずは複雑なことはしない予定で、行列の掛け算とか対角化ぐらいが簡潔に書けると嬉しいです
久しぶりにC++再開したが
昔からだが
PHPはC++のスクリプト版といえるかのように文法・関数が似てるから
プロトタイプをPHPで作成したほうが時短になるかと?
仮想コードによるアルゴリズムの記述やフローチャートなどに近い
行列の掛け算とか対角化ならPythonかマキシマでいいとおもうが?
大規模だともしかしたらC++のほうが早いかもしれないが
PythonだとGoogle ColaboratoryとかでGPUをネットワーク使用できたりするが
Colaboratory とは
Colaboratory(略称: Colab)は、ブラウザから Python を記述、実行できるサービスです。次の特長を備えています。
環境構築が不要
GPU への無料アクセス
簡単に共有
https://colab.research.google.com/notebooks/welcome.ipynb >PHPはC++のスクリプト版といえるかのように文法・関数が似てる
迷惑するから出鱈目言うな
因果が逆だろう。
似た使い方しかしない人間にとっては似て見えるということもあるんだろうさ。
制御構文が似ていれば似ているように見える人というのは一定数いる
それしか使わないから
C++のこともphpのことも両方ニワカじゃないとなかなか出てこない発言
昨日今日入門書めくってるくらいのレベルじゃないとなかなかできない発言
template<class T>
void f(T x) {
auto a = x, b = 0;
}
f(0.0);
これgccだとコンパイル通るけど規格的にはダメだよね?
autoの推定がxから導かれるdoubleと0から導かれるintで矛盾しないかって話
そもそも何の規格だよ
問題あるなら書き直せばいいだろ
https://eel.is/c++draft/dcl.type.auto.deduct#def:placeholder_type_deduction For a variable declared with a type that contains a placeholder type, T is the declared type of the variable.
https://eel.is/c++draft/dcl.spec.auto.general#7 The type of each declared variable is determined by placeholder type deduction, and if the type that replaces the placeholder type is not the same in each deduction, the program is ill-formed.
Draft これでいいか分からんけど、多分ダメですね
a と b は個別に型推論して、同一でなかったら ill-formed であると読める
0の部分static_castしなきゃ駄目ということか。なるほど
g++ 10.3.0は-pedantic指定しても通すな
C++とPHPが似てないというニカワかと?
Pythonやルビーやjavascriptよりも似てるだろ?
C++にある関数をそのままPHPでも使えるようにしてあるのが多いし
>>201 これやってみ
cout << typeid(0).name();
C++Builder使った後にVisual Studio使って、
二層作ったらC++Builderがめちゃくちゃ簡単で
作りやすかったんですけど私の感覚、何か変?
Visual Studioより効率いい気がしました。
20年以上前ならいざしらず今C++Builderなんて使おうとする人は変としか・・・
20年以上前は言い過ぎ
自分は2009を大事に使っている
うちでは2000年以降のborlandはそれ以前に開発されたものの保守以外で使用することはなかったから
2000年以前でもほぼMSVCの独壇場だった
BuilderというよりRAD Studioやろ?
>>14 数学記号増やしたところで、数学記号はレイアウトの問題がかなりついて回るのであまり意味ないと思うけどなあ。2^2^2^2とか、定積分とか、分数とか表現できないでしょ。
そういうのは組版の問題。
まあ、たしかにイタリックのxとかはあるのに、イタリック(?)のπはないとかは、中途半端な気はするけどね。
std::set にラムダ式渡すとき
std::set<T, decltype(comp)> s(comp);
ってなるのダサすぎるんだけどどうにかならない?
std::set<T> s([](T x, T y) { return x < y; });
みたいに直接書きたい
make_set みたいな関数テンプレート用意すれば解決するのはわかるんだけどクラステンプレートだとどうしてダメなんだ
あとこれが自作クラスだった場合推論補助とかでどうにかできるんだろうか
>>214 これなら通るんだけど
template <typename T> std::set(T(&)(T,T)) -> std::set<T, T(&)(T,T)>;
int comp(int x, int y) { return x < y; }
std::set s(comp);
compをラムダやテンプレートにするとdeductionに失敗するね
>>213 だからさー、あなたが使うフォントで期待したπが表示されないのはフォントのデザイナの問題であってunicodeの問題じゃない
ちゃんと区別できるようになってるんだから
>>214 std::function<bool (T,T)> 使っちゃダメなの?
>>216 どうでもいい絵文字よりは、数学記号は考慮してほしかったですよね
というかピクトグラムの意味がわかりません、漢字の方がマシ
>>214 std::set s(std::initializer_list<T>{}, [](T x, T y){return x < y;});
とかどうやろ
>>215 ありがとう
悲しい
>>217 比較関数って内部でめちゃくちゃ呼ばれるんでパフォーマンスが気になっちゃう
>>223 なるほどTも推論させればいいのか
トリッキーだけど一番思ってたのに近いかも、ありがとう
(float) std::sin(3.14);
これの三角関数の左の(float)ってどういう意味ですか??
あなるほど
C形式のキャストでdoubleからfloatに変換してるんですね
C形式のキャストでええやろ
C++ならstatic_castでキャストするべきところ
>>230 いや、そうではなくJIS規格で定められた用語ってこと
・・・まあね、フレンドが随伴とかちょっと・・・なところあるんだけど
C++11以降にJIS規格は存在しないし, ぶっちゃけ本当に誰もキャスト形式なんて呼んでないし (T) cast-expression とさえ呼ばれない。
C++ Core GuidelinesやgccやclangでもC-style(やold-style)と表現しているのだからそんな古臭い分かりにくい用語を押し付ける必然性がない
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-cstylecast 用語の間違いで意味の取り違えが起きるような場面ならはっきりさせておくべきだが今回はどうでもいいな。
>>234 キャスト形式?
何に対する意見を言っているんだ?
揚げ足じゃねえよ
話の根幹に拘わることだ
まともに反駁できないなら
黙っているのが得策だぞ
訂正の益があったとしても(今回は全くなさそうだが)用語警察は不要
書き込みの意味が文脈から一意であれば問題ない
黙ってろ
constructorとdestructorを常に生成子・消去子と呼んでる者だけがJIS規格を振り回しなさい
オレ用語を高圧的な態度で押しつけてくるやつとは仕事したくねえ
>>219 今から考えれば NECのPC-8801 のBASIC言語は数学好きに合っていた。
当時のNECの社長は、東大物理の大学院出の人だったらしい。
その人がTOPにいる間はNECのパソコンは日本で一斉を風靡していたが、
その人が降りてからは、嘘の様に勢いがなくなった。
コルーチンはいろいろ制限が多くてな、最近はfiberの方を使ってる
機種依存APIを使う必要がある、実行効率が若干落ちる、スタック用のメモリを大量消費する、トレースデバッグがやりづらい等のデメリットはあるが、
本物のyieldはやっぱ便利よ
c+のvectorって無限に要素追加したらどうなりますか?
例えばwhile (1) でemplace_back()し続けた時の挙動です。javaみたいにちゃんとoutofmemoryエラー吐くようにできてますか?
「ちゃんとout of memoryエラーを吐く」というのは突き詰めるとものすごく難しい概念なので、どこまでを求めるかによる
Javaにしても本当にどのレベルまで正しくやれてるのかは知らん
まあ「なんかあったらstd::bad_alloc投げて来るやろ」で99%のケースは事足りると思うけど
例えば普通のアプリだと、C++とか関係なく最近のOSのメモリ確保は仮想メモリの確保なので、実際にそのアドレスが使われて初めて物理アドレスが確保され、スワップ領域が足りない場合もそのとき検出される。
mallocに失敗すればbad_allocが投げられるが
実際のところmallocが失敗するときにできることは殆ど無いと認識している
>>179 そもそも C++ から Fortran で書かれてるオリジナルの BLAS とか LAPACK を呼ぶこともできるのだから、その辺は別に何でも良い
そんなことよりも多次元配列をどう持つかの方が C++ にとっては難しい課題だ
Cの多次元配列や一次元配列として持つのはユーザ側の負担が大き過ぎる
boost の multi_array は放置されている (move セマンティクスに対応してすらない)
xtensor みたいなサードパーティのものをわざわざ使うのも…… (つーかどれもパッとしない)
早く多次元配列くらい公式で用意してほしい
class foo : vector<mystruct>
みたいなクラスを作っているんだけど
クラス内の関数で自身の配列の構造体の関数を呼ぶにはどうしたらいいんだろう?
this[a]->set(0);
と書いてもメンバーがありませんと出て困ってます😭
>>252 ありがとう!ちょっと直したけど
(*this)[a].set(0);
でできました、超助かりました!チュッ!
atは範囲チェック分鈍くなるの我慢出来るなら有
あと例外飛ばすからtry〜catch節必須
>>248 bad_alloc is not out-of-memory!
https://wg21.link/P1401 std::vectorのデストラクタはvirtualじゃないから気を付けてね、念のため
abort()したら生きている自動オブジェクトは
どうなってし
まいますの?
#include <iostream>
#include <cstdlib>
using namespace std;
struct s {
~s() {cout << "called." << endl;}
};
int main() {
s a;
abort();
return 0;
}
https://ideone.com/YDdO5O https://cpprefjp.github.io/reference/cstdlib/abort.html abortより例外飛ばした方が確実だな(VC++6.0を除く
>>258 デストラクタは実行されない
問答無用で強制終了
電源ぶっちするようなもん
多次元配列 (mdspanだっけ) ってまだSTLに入らんの?
線形代数アルゴリズムはBLAS、LAPACKはじめ外部のライブラリに頼らざるを得ないんだから、最小限の機能だけ備えた取り回しの良いライブラリをさっさと入れちゃえば良いのに
この機械学習全盛の時代に置いてかれるよね
ああいうライブラリってプラットフォームにべったり依存してるんじゃないの
GoogleのGPUがオンラインで無料でつかえるぞ
Python言語だが
C言語とかローカルの言語からGoogleのGPUを操作できれば
ローカルで実行してるのと大差なくできると今おもったが
探せばすでにそういったAPIとかある気はしたが
スレ違い。
Google Colaboratoryはjupyter notebook使えればいいだけ。
!や%%で大抵のことは出来る。
>>260 例外飛ばしたら今度はCの関数が処理の途中でぶっちされるやん……?
次のような場合:
foo() // C++で記述、例外をスロー
↑
bar() // Cで記述、ループ内とかでfoo()を呼ぶ
↑
baz() // C/C++で書かれた呼び出し元
構造体を関数の中で宣言して戻り値に入れたら
呼び出した側が受け取った値はどこかで開放しないといけないですか?
なんで最近こんな無茶苦茶なの?
>>269 質問は「生きている自動オブジェクト」がどうなるかであり、例外でスコープから抜ければC/C++だろうと破棄される
>>270 「関数の中で宣言」とはどういうこと?
「受け取った値」はどうやって確保されたの?
ちゃんと伝えられないならコードで質問しないと伝わらない
>>270 要らない
構造体はintなんかと同じでコピーされるから
>>272 >>271 ありがとう!助かりました
C#でGC慣れしているので
正直この辺はなかなか理解が進まなくて…
ESP32が面白くてC++を始めたんだけど
いざ自分であれこれ作ろうとすると
わからない部分が多すぎて申し訳ない
そこらへんのメカニズムはどんな入門書にでも書いてあるはずだよ。
C# の経験があると C++ の入門書では重複する考え方も多くて馬鹿らしく思うかもしれないけど、
似て非なる機能や用語で混乱しないためには基礎から学んだほうがいい。
newを知っててもdelete知らなかったりするからな
そこらじゅうにうんこをばらまいておいて誰かが始末してくれると信じているというわけか
やつらメモリーリークという言葉自体知らなかったりするから
GC言語でもファイルのcloseはあるから
C++はメモリもあれと同じでnewした物は全部責任持ってdeleteしなきゃならないんだよって教えるんだけど
みんなこの世の終わりみたいな顔する
おまいら「よう、うんこ掃除屋」
unique_ptr「…」
10年後、人類はAIの反乱で滅亡するのでした
>>282 Cで書かれてるならデストラクタなどはないのでメモリ解放で破棄
Cの構造体はunwindされずただぶっちされるだけ
コードの実行がぶっちされるのはC/C++共通う
自身を適切に開放なり後始末なりするデストラクタを持たないオブジェクトは例外でほぼ等しく致命傷を負う
そういうデストラクタを持っているつもりでも、コードの実行順がぶっちされることにより、
プログラマーの不注意ですぐ致命傷を負う
cat >sample_cpp.cpp <<EOF
#include <iostream>
using namespace std;
struct s {
~s() {cout << "called." << endl;}
};
void func1() {
s a;
throw "hoge";
}
extern "C" void func2(void(*)());
int main() {
s a;
try {
func2(func1);
}
catch(const char* m) {
cout << m << endl;
}
return 0;
}
EOF
cat >sample_c.c <<EOF
struct s {
int dummy;
};
void func2(void (*f)()) {
struct s a;
f();
}
EOF
gcc -g -c sample_c.c
g++ -Wall -g -c sample_cpp.cpp
g++ sample_c.o sample_cpp.o -o sample
./sample
実行結果
called.
hoge
called.
>>284-285 Cにはデストラクタがないので、メモリが開放されればOKであり、自動的に開放される
C++ではスコープから外れればデストラクタが呼ばれた後にメモリが開放される
JavaScript でリソースを解放 (GC で回収) するために
変数に false を代入して参照を切っているのを見たことが有って、
GC があってもこの手のバッドノウハウは要るんだなと思いました。 (小並感)
GCが正常に機能しているという保証がそもそもないから
そもそも何が正常な動作なのかを誰も責任とらない架空の権威によって成り立っている
メモリ回収のタイミングが保証されないのは大した問題ではない
(プロセスが終了すればどうせ回収されるので)
のだが、外部のリソースを掴んでいるときに後始末されないかもしれないのは困るな。
Windows10でコマンドプロンプトのGUIを提供するconhost.exeはナウくてヤングなC++のstd::basic_string_viewを使っている
Windows2000以来のconhost.exeが古いコードのままメンテ放置されているわけではないことがわかり少しだけほっこりする
以下、それらしきシンボル
TextBuffer::InsertCharacter(class std::basic_string_view<unsigned short,struct std::char_traits<unsigned short> >,class DbcsAttribute,class TextAttribute)
ま、本当はなにをしたかったというとpwsh.exeとconhost.exeが道連れクラッシュして困ってるってだけなんだが
多人数のプロジェクトほどuniqueではなくshard_ptrが増えるのはトラブった時に誰も責任取らなくていいからって事?
shared_ptrを乱用する職業PGよりもweak_ptrを使いこなせる厨二PGたれ
主従関係がある場合、主が従のシェアポを持ち、従が主のウイポを持て
多くの職業PGは依存関係を親子関係で騙りたがるが、
生物学上、親は子より先に生まれ先に死ぬのだから、FIFOは成り立つがLIFOは成り立たない
ポリコレ的にはマスター/スレーブではなくプライマリ/セカンダリが望ましいとされる
ルー語の乱用をさけるならばプライマリ/セカンダリではなく主/従がなお良い
よって依存関係を主従関係で騙るのが正しい
織豊政権のように、主君の死後に従者が取って代わった例もあるから完全ではないが
秀吉は主君信長のweak_ptrを持っていたので本能寺の変での主君の横死を的確に知ることができた
くだらねえ
喩え話なのはみんなわかってんのに
覚えたての日本語ひけらかしてドヤるな
>>290 そうなんだよね
リソース解放のタイミングが保証されないのは言語設計のミスだった
JavaではファイルやソケットなどのリソースはGCのときに呼ばれるfinalizeで解放すればいいよって思想だったけど
いつfinalizeが呼ばれるのか予測できないことに起因するバグが多発
ついにfinalizeが廃止されることになった
リソースは自前で廃棄してねというスタンス
GCも当初の期待ほどうまくいってない
ファイルやソケットの開放はcloseないしデストラクタでやるのだから保証されてるぞ?
保証されないのはメモリリソースだけ
あとjavaも当初からfinalizeが呼ばれることは保証されてなかったからfinalizeで開放しなさいなんていう慣習はなかったと思うが
JavaはJDBC周りのGCの挙動が厄介だYO
GC性善説に立つと痛い目にあう
>>299 JavaやC#にはデストラクタないからね
C++経験者がJavaやC#ではファイナライザーを使ったりしてたんだよ
C#ではマイクロソフト謹製標準ライブラリでさえファイナライザーでファイルを閉じるクソコードがある
いつまでスレ違いの話続けんの?間違いの指摘すら面倒
C#はファイナライザで解放でいいんだよ
Disposeパターンがそういうスタイルだから
>>301 それはその個人が不勉強なだけだろ…
finalizeが呼ばれないことがあるのはあまりに初歩的なチップスで、初級でない一般的なJavaプログラマがfinalizeだけでリソース開放するとかありえない。
思想って誰の思想?
メモリ解放に気を使わないC/C++プログラマがいないのと同じ
>>304 その不勉強な個人が多すぎたんでしょ
デストラクタの代わりにファイナライザーを使う誤用が多かった
finalize廃止を決断しなければならないほどにね
>>ID:Qqc0ky4z
>>298 >JavaではファイルやソケットなどのリソースはGCのときに呼ばれるfinalizeで解放すればいいよって思想だったけど
>>301 >C#ではマイクロソフト謹製標準ライブラリでさえファイナライザーでファイルを閉じるクソコードがある
>>305 >その不勉強な個人が多すぎたんでしょ
上記発言を見ればあなたが不勉強なのはわかったよ
vectorのaが空じゃないと思い込んでて実は空の状態で
for (int i =0; i < a.size()-1; i++)
これやると一瞬でオワるのなんとかならないかな
まあ普通はa.sizeをintやらでキャスりましょーって話だとは思うけど
そもそもsizeの型がuなのが悪いと思うんだが
uじゃなきゃ足りないくらいの要素数確保することなんてあんのか?ぁん?
または、if(!a.empty()) for(...)
i <= a.size()-1じゃなくて i < a.size()-1?
以下のような直感的でベタな条件式のほうがいいと思うよ
for (int i =0; a.size() > 0 && i < a.size()-1; i++)
一見すると小学生の書いた作文っぽく見えるコードが結局のところ一番良い
厨二を拗らせたような難解なコードは避けよう
このループ内でa[i]とa[i+1]を使ってなんかするんだろ
a[i+1]が有効なインデックスか?という条件がi+1<a.size()でこれは自然
出典忘れたけどsizeが符号無しなのは標準委員会も失敗だったと考えてるらしい(?)
まあ、そうでなきゃssize_tなんて恥ずかしいもの後付けしたりしないし
最近このスレやばない?
intじゃなくてstd::vector<...>::size_typeでいい
>>310は明らかに間違ってる
1引くケースは大抵サイズ2以上がよくある事前条件なので普通事前に弾く
ループ内や別スレッドでvectorが変更されないケースならループの外で1引いた方が速い
今回ssize_tは無関係
>>323 列挙したところ。普通にレベルがやばい。
>>310はwhile(!a.empty())と書いてるのかと思ってたので俺の勘違い。
何が普通に動くの?
>>324 いや、間違えてるとか言われてたからな
頭の中で動かしてみて問題なく普通に動くだろうと
ってなんでお前そんなにエラそうなの?エラが張ってる民族か?
>>325 聞かれたから答えたけど会話にならんな・・・この辺で
どうしたらいいかご意見を聞かせてください!٩( ᐛ )و
class hogeにおいてメンバ変数unique_ptr<toge>toge1を所有しております。
vector<hoge> vHogeを運用するとき、hogeのインスタンスをプッシュバックしようとすると、削除された関数ですというエラーメッセージが帰ってまいります。
おそらくtoge1がユニークポインタであり、ムーブ以外の移動が不可能だからだと思うのですが……このままプッシュバックさせるのに何か方法はありますでしょうか?
健作でtoge1にshared_ptrを使う、hogeのコピーコンストラクタにmemcpyを使う等の解を見つけました。
私ごとですが、shared_ptrは循環参照で失敗した哀しい過去があり、恐怖感があります。
またmemcpyでユニークポインタをメモリコピーする場合の機序がイマイチわかりません……
ムーブを経由させずにどうやってユニークポインタを再確保出来る証拠でしょうか……?
どちらの方法でも、実行する場合の注意点があればなんでも教えていただければ幸いです(^O^)/
また上記以外の方法も、もし存在するならば教えていただけると嬉しいです(´;ω;`)
先にお礼申し上げます。ありがとうございます。
>>326 もとはといえオメェが勘違いしたからだろこのヒトモドキが
>>327 再現コードをどこかに貼って。伝わらない。
>>328 煽ってるだけじゃんw だから会話にならないんだよw
>>322 普通事前に弾くとかドヤ顔で言われてもそんなの200も承知の助なんだよ
ああいう不測な組み方で死にかねない爆弾抱えるデメリットに比べたら
unsignedなことによるメリットなんて実質ほぼないカスみたいなもんだからsizeがunsignedなのは設計ミスではって話
申し訳ございません( ✌︎'ω')✌︎
遅れましたがこれです。
プッシュバックでエラーががが
struct Toge{
int a=0;
};
struct hoge {
std::unique_ptr<toge> toge1;
};
int main ()
{
std::vector<hoge> vHoge;
hoge hoge001;
vHoge.push_back(hoge001);
}
大文字になってしまった……
struct Toge >>> struct toge
と思っていただければ……
vHoge.push_back(std::move(hoge001));
vectorに突っ込んだらもうhoge001は使わないんだったらvHoge.push_back(std::move(hoge001));
コピーさせたいならhogeにこんなコピコンとコピop=を定義しとけばいい
hoge(const hoge& other) : toge1(new toge(*other.toge1)){}
基本はmoveだけど時々コピーもしたいくらいなら特殊関数じゃなくてclone()みたいな関数にしておく
どれがいいかは本当の用途と目的で選んで
>>332 コンパイルエラーを直してください
https://ideone.com/RxQYii >>330 承知してるなら弾け
今回の用件はsize_type使えばいいだけなのでunsignedかどうかは関係ない
>>327 > hogeのコピーコンストラクタにmemcpyを使う等の解
これについてはダメ。
設計上の話ではなく言語仕様での保証がない。
そんなのがまかり通ったらスマートポインタの意味がない。
型が trivially copyable の要件を満たすときだけ memcpy でのコピーが許されている。
>>335 オメェが直して差し上げろよ
本人それで困ってんだからよ
>>337 なんだか煽ってばかりですね。質問内容は明快にしないといけないので。
>>335 いや関係大ありだから
ないって言い張るならsizeがunsignedなメリット挙げてみなよ、ないでしょ
>>333 >>334 お風呂に入っており返信が遅くなりました。
なんてお礼を言ったらいいか、std::moveで解決しました。
自分の知識不足ではありますが、素早い返信に感謝でございます(〃ω〃)
生成したユニークポインタはベクターに移せれば使い捨てのでムーブで良さそうです。
std::moveについて調べてみます!
>>336 ありがとうございます。
メモコピーで解決するというページがあったのですが、正直機序がわからず不安でした(笑)
シェアードポインタかムーブで対応したいと思います。
有難うございました。
>>308 普通は範囲forじゃないの?
性能とかで差分あったっけ。
>>340 関係ないでしょw vectorの要素指定に必要な型はsize_typeだからw
>>343 ふ〜ん、で?
sizeがunsignedなメリット挙げれるの?挙げれないの?
>>344 同じ人かなw 最初から最後まで関係ないとしか言ってないよw 関係ない話をする意味はないw
はい逃げたねお疲れさまー
てかまあこんな頭の固いジジイ追い詰めなくても
>>319-320あたりで結論出てるからもういいんだけどね
sizeも漏れなく頭の固いクソジジイが設計ミスしたんだろうなぁ
間違いを認められるだけコイツよりまだマシだけど
>>346 煽るだけで根拠も出せてない無関係な話をしてるのはそっちでしょw 話が終わらなくなるなら普通はしないw
頭が硬いのは君だよw
>>341 もう見てないだろうけど、
>>331のケースだと
わざわざstd::move()で右辺値にキャストしなくても
vHoge.push_back(hoge());
で良いと思う。
hoge hoge001;とするから左辺値になってしまってstd::move()が必要になるけど、
引数で直接hoge()とすれば右辺値だからstd::move()しなくても右辺値参照のpush_backが呼ばれるはず。
>>350 今でしょ・・・
>>349なんてしなくても
vHoge.emplace_back();
で良い話だった。
>>349 ありがとうございます!
エンプレイスバックでも確認できました。
本当に根本がわかってなかったにでお恥ずかしい話ですが、ユニークポインタはmove出来ることは知っていても、インスタンスごとmoveするという考えに至りませんでした。
右辺値の言葉だけは知っていた状態です……
moveが引数の領域を右辺値に変換するので、インスタンスのメンバ全てが一時的に右辺地に変換され、その結果ユニークポインタの移動も許可されるという考えで良いのですかね?
皆様ありがとうございます
gccのヘッダファイル見るとpush_backがemplace_backに置き換えられてた
質問する方はそもそも何を知りたいのか、どうしたいのかを明確にせず
回答する方はよく分からずに回答してる感じだな(はちみつ餃子以外)
俺ははちみつ餃子じゃないよ
分かってる人は全員そう思うと思う
このスレやばい
>>354 おまえさんの対話力が、ここの平均以下ってことだな
僅かなエスパーもできないアスペっぽいやつが
取り残されるのは仕方のないことだ
上司や客に言われたことを自分も誰かに言いたいのかな
>>357-359 3連投しないで1つにまとめてね
伝わらない人がいるのでハッキリ言うと、、、
質問したい人はもう少し明確に質問してほしい
回答する人はもう少し正確な回答をしてほしい
現在このスレのレベルはかなり落ちている
>>360 あんたに連投がどうのと指図される筋合いはないし
質問者がどうして欲しい
回答者がどうして欲しい
と、やたら依頼心の強いやつだな
頼み事をする態度を知らんのか
>>361-362 見るに堪えないだけだよ。当たり前のことを要求してるだけだし、ID変えてまで一体何が気に障るのやら・・・
簡単なコードが提示できないんだけどコンセプトで以下のようなエラーがでる
> C7608: アトミック制約は定数式である必要があります 。
アトミック制約ってなに?
1つの内容を理由もなく複数のレスに分けて投稿する奴はもれなくバカなのでスルー推奨
多分atomic は、OS に割り込まれない、interrupt disable みたいな奴だろ。
割り込み禁止区間
1. 割り込み禁止
2. atomic に処理したいもの
3. 割り込み許可
>>367 それはリアルモードOSでの話
最近の OS ではユーザーが OS の企みを阻止することは不可能
無関係でスレ違いかつ「内容まで間違った」ことを垂れ流し続けるのはやめてくれ
一般にアトミックと割り込み禁止は異なる概念、
マルチコアのアーキテクチャーなら割り込みを禁止したからといって
複数回のバスサイクルをアトミックに遂行できるとは限らない
つなみに割り込み禁止という手段でOSに割り込まれないことは実現はできるが
強力すぎるので普通はそれはしない
やったらリアルタイムOSならリアルタイム性の前提が根底から覆るし、
非リアルタイムOSでも割り込み禁止したタスクAとは本来無関係(独立に実行して良い)なタスクまで
プリエンプション停止によって止まってしまう弊害があるから
リードモディファイライトぐらいなら今日日のCPUが命令を備えているのでOSにも対応するAPIがあり、
それを実行したらリード、ライト、リードの3バスサイクルがアトミックに実行される
もっと凝った処理をアトミックにしたい場合は
1. クリティカルセクション(セマフォとかでも良い)にENTER
2. atomic に処理したいもの
3. クリティカルセクション(セマフォとかでも良い)からLEAVE
となり、1と3はやはりOSにお世話いただく
>>363 出た、当たり前のことを要求だとよ
自分の要求は通って当たり前と思っている真性のやつw
>>371 クリティカルセクションとイベントを使って書いていたことがありましたが、スタベーションに悩まされて止めてしまいました…
>>373 なんでatomicに処理するごときでイベントが出てくるのかわからん……
1で待っているタスクBが居るなら、アトミックな処理を終えたタスクAが3を実行した時点で
OSがタスクBに自動的に通知する(ていうか起こす
不必要に凝りまくった(そして間違った)排他制御をしているのではないか、
>>376 迷惑なんでコテハンにしていただけません?
何が迷惑なのか理由の説明がないが、コテハン付けたいならお前だけ勝手につけとけw
template <typename T, typename Allocator = std::allocator<T>>
using vec = std::vector<T, Allocator>;
auto v = vec(0, 0);
ってgccだと動いてclangだとコンパイル通らないけどclangのバグ?
勘違いしてた
セマフォでも一人に限定すれば問題ないか
そもそもそもそも
アトミック制約って原子制約のことでしょう
排他制御のatomicとは全く無関係に
単にconstexprじゃないbool値をrequiresしてませんか?
>>379 バグというか C++20 対応が不十分なんだと思う。
@ 元々は実引数から型引数にあてはまる型を推論するのは関数テンプレート (メンバ関数テンプレートを含む) でしか出来なかった
A C++17 コンストラクタの実引数からクラスの型引数を推論できるようになった
B C++20 からエイリアステンプレートを挟んでも推論できるようになった ← これがまだ出来ない
>>381 たしかにこれの最初のサンプルのdraw関数みたいな事をrequiresしてる。
https://cpprefjp.github.io/lang/cpp20/concepts.html ただ上で言うdraw関数はconstexprなんだけどな・・・
>>382 わかりやすかったありがとう
まだmake_hogeみたいな不格好なヘルパ関数が役に立つこともあるのね
NFTアートとNFTゲームとGameFiとブロックチェーンゲームに
提供する側・作る側として参入しよう。
(むりなら参加する側でもいい)
DAOとPlay-to-Earn(遊んで稼ぐ)が世界の未来になる
C#で作成されたDLLってC++で呼び出せないんでしたっけ?
>>386 c++cliのラッパdllを挟んでc#dllを呼ぶとかc#dllをcom参照可能にするとか.NET DLLExportを使うとかあるよ
>>388 そういうのはできるかどうかを含め、どういう環境で何を対象に何をしたいのかによる。
そんなことすら書いてない人にいきなりキーワードをあげる必要はないよ。
技術に関しては不正確な情報を垂れ流すことほどの害悪はない
悪意を持って嘘をつくのはいかんが
信じていたことが後に間違っていたことに気付くことはあり
それへの虞を言い訳に何もしないやつと
自らの誤りに気付いたときに潔くないやつは生ゴミだ
>>394 Linux環境ではC#のCOM相互運用できないとか、かなあ?
>>387 君は役に立たんなw
>>388 ありがとう
やっぱそういう方法になるんだね
>>394 今回の話で言えば条件によっては動かないのにさも動くかのようにミスリードする情報
相手の勘違いを指摘する機会がないことにより、結果的に回答にならない情報
>>395,397
ありとあらゆる環境で動く回答しか認めないとかアスペ全開やなw
>>398 普通ですよ。環境はおろか困っている状況すら何も書いてないのだから。普通に釣りの気配しかありません。
あと加えて言うならば、一般に・・・という話なのですが、
runtimeでVMを動かすような言語の場合、あまりnative側からキックするような使い方をしません
組み込みなど、そうせざるを得ない特殊な状況のときくらいですね
んで根掘り葉掘り聞くだけ聞いて結局回答しないパターン、ってのはよく見るな。
>>401 それは分かりもしないのに回答しようとしたケースですね
全条件想定しないで回答しようとするとそうなります
もちろん聞いたことに答えがない場合も回答する機会は来ませんけどw
浮動小数点の0.0以外の真偽値って規定されてるんですか?
2.0 == trueが偽になるのにif(2.0)は真のように振舞うのでよく分からなくなりました
0は偽でそれ以外は真
if(5) も if(10) も 0 以外だから真
5も10も真だが 5 == 10 は当然等しくないため偽になる
if (2.0 != 0)はあんまり正確じゃないけどねw
当然ながらbool(2.0) == trueとすれば真になるよ
bool(2.0) == true
2.0 == double(true)
で曖昧にならない
こういうのoperatorとctorでは作れないもんかね
最近本当に質問者も回答者も酷いな・・・日本語からやばい
>>410 何が曖昧だと言っていて、こういうのってどういうのなんでしょ?
>>411 え?じゃ何も伝わらない
そういうのを求めるなら上級者の相談室でも作ってそこにいればいいじゃない
人のやり取り見て文句いうだけの人なんて居ても邪魔なだけだし
そんな難しい要求してないんだけどw
一応↓なスレッドもありますよ
0からの、超初心者C++相談室
http://2chb.net/r/tech/1542002113/ 何も言ってないやつとじゃ話にならん
マウント取ったつもりになってろよアホ
ID:XiOitZFG
またコイツ自分賢いと思ってる例のガイジか
std::array<std::array<int, 2>, 2> a{1, 2, 3, 4};
だとコンパイルできて
std::array<std::array<int, 2>, 2> a{{1, 2}, {3, 4}};
だとコンパイルできないのってなんでですか?
下は内側の初期化子リストの型推論が上手くいかない気はするのですが上がOKな理由が全然分かりません
arrayは設計悪いね
string_viewみたいなラッパーのほうがマシ
arrayはそんなに設計の余地ないし別によくね
ラッパークラスは役割が別だし比較する意味がわからん
>>418 こうすればいけるね
波括弧が一つ余計に必要なのがなあ
std::array<std::array<int, 2>, 2> a{{{1, 2}, {3, 4}}};
>>418 >>420,421 の見解が適切
構造上は以下と等価
struct S1 { struct S2 { int e[2]; } s[2]; };
なので、中括弧を丁寧に書くと↓が正しい
S1 s{{{{1,2},{{3,4}}}};
質問でエラーになったケースは、上の例でメンバsを{1,2}で初期化しようとしため、{3,4}が余ってエラーになる。
https://en.cppreference.com/w/cpp/language/aggregate_initialization >>421 >>422 ありがとうございます
配列をメンバに持ってるので本来は波括弧が二重に必要になるんですね
今までは1次元でなんとなく配列と同様で動いていたので省略しているという認識がありませんでした
a{{1, 2}, {3, 4}}で初期化できるようにしようぜっていう提案もあったけど
初期化ルールがますますカオスになるので却下された
テンプレートで関数の引数を書く方法がわからないんですが
sort(V.begin(), V.end(), ラムダ式)
を自作するにはどうやればいいんでしょうか
まず日本語から勉強してください
「テンプレートで関数の引数を書く方法」と「sort(V.begin(), V.end(), ラムダ式)を自作」には何の関連もありません
まず日本語から勉強してください
「テンプレートで関数の引数を書く方法」と「sort(V.begin(), V.end(), ラムダ式)を自作」には何の関連もありません
自己解決しました
リンク先みながらこれで出来ました
template<typename FNC>
void usort (FNC&& fuc) { cout<< fuc(2) <<endl; }
int main() {
usort( [](int x) { return x+2; } );
}
https://zenn.dev/rita0222/articles/4bb5023e48c134 質問と回答はおろか日本語も覚束ない人の記事の宣伝はどうかと思いますよ
ごめん例のアスペじゃないけど俺もこの質問は日本語がひどいと思う
「テンプレートを使って、関数を引数とする関数を書く方法がわからない」でいいんだよね?
「で」も「の」も意味が複数ある助詞だから次から気を付けような
VC++の質問になってしまうかもしれませんがよろしくお願い致します。
void Func() throw (const char*);とした関数で静的に例外の型チェックをしてコンパイルエラーなり吐いてもらうことはできないのでしょうか?
try { Func(); } catch (const wchar_t* ex) {}と書いてしまった場合等にコンパイルエラーを出してもらいたいです
例外指定はもうすぐ消えてなくなる機能だから使うのやめた方がいいよ
例外指定は調べたらC++17で削除されてんだな。
例外指定は実行時のチェックで意味ないと思ってたから一度も使ったことない。
throwで投げる例外を指定するのはC++11以降非推奨でC++17で削除された
例外を投げ得ることを示す(空の)throwもC++11以降非推奨でC++20で削除
https://ja.cppreference.com/w/cpp/language/except_spec 結論としては無理
意味わからんもんなthrow接尾子
投げる例外全部把握出来んのかよって
ファイルオープンの失敗をどうやって間違えずに処理させるんだよ
20年ちかくそれがいいことだっつってやってたんだぞ
void aho() throw(std::bad_exception);
ポインタ型変数のスタック消費が4バイト(32bit OS)または8バイト(64bit OS)なのはわかるんだけど、
参照型変数ってスタックを何バイト消費するの?
>>441 GCC の資料によれば Itanium C++ ABI に従う。 (Itanium 以外でも ABI は Itanium ということらしい。)
https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.cxx_interface で、 ABI のほうでの定義では引数・返却値における参照の実態はポインタだし、
POD のレイアウトとしても参照はポインタのように扱われる。
https://itanium-cxx-abi.github.io/cxx-abi/abi.html#reference-parameters https://itanium-cxx-abi.github.io/cxx-abi/abi.html#reference-return-values https://itanium-cxx-abi.github.io/cxx-abi/abi.html#pod 内部的には参照はほぼポインタだと思っていいんでないの。
自動でデリファレンスするポインタって感じ。
ちなみに言語仕様的には参照はオブジェクトではなく参照先のオブジェクトの別名のように扱われるので、
sizeof に渡したときには参照先の型の大きさが返ってくることになってる。
sizeof(int&) みたいにしたら sizeof(int) と同じ意味になるってことね。
確認してみた。
$ gcc -x c++ -S - -o - <<EOF | sed -n '/^main:/,$p;/\$2/q'
int main() {
int a = 1;
int& r = a;
r = 2;
return a;
}
EOF
main:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $1, -20(%rbp)
leaq -20(%rbp), %rax
movq %rax, -16(%rbp)
movq -16(%rbp), %rax
movl $2, (%rax)
参照先が見えてるところでは
参照先へ直にアクセスしてコストゼロだったり
参照引数をとる関数でもインライン化された場合はゼロ
てなことがなければポインタ1個分
そういうのは最適化なので無関係
$ gcc -O3 -x c++ -S - -o - <<EOF | sed -n '/^main:/,$p;/ret/q'
int main() {
int a = 1;
int& r = a;
r = 2;
return a;
}
EOF
main:
.LFB0:
.cfi_startproc
endbr64
movl $2, %eax
ret
最適化する前の意味合いとして
ポインタ1個分のコストを必ず発生するという規定なんかあったか?
444へのレスで最適化がどうたらぬかしといて
そんな話はしてない、かよ
アセンブラ貼ってた威勢はどこへ吹っ飛んだんだかw
いいよ、逃げたきゃ逃がしてやるよヘタレ野郎
最初から処理系(gcc)の話しかしてない。規定の話をしてるのはお前だけだ。早く貼れ。逃げるな。
unique_ptrオブジェクトとその実体を参照する参照型を使えば、
スタック消費を抑えつつスタック変数を使っているかのようなソースコードが書けそうだけど
それは全くレイヤーの違う話
アプリのコンテキストを構造体/クラスにしてヒープかスタティックに置くだけで実現できる
実現手段としてunique_ptrを使いたいなら使えばいいというだけ
>>451 ひょっとして ID:c8hM8/Kk かな?
無意味な煽り書き込みやめてくれ
構造体/クラスをヒープに置いたところで、その構造体/クラスのメンバー関数でスタック変数を使ってたら意味がないだろ
何が問題提起されているのか理解してから書き込んでくれ
スタック消費を抑えたいなら静的に確保するかヒープを使えばいいというだけの話でしょ。
struct app_context {int x;};
void func_old() {
int x = 0;
}
void func_new(app_context* ctx) {
ctx->x = 0;
}
int main() {
auto ctx = new app_context();
func_old();
func_new(ctx);
delete ctx;
return 0;
}
各関数/メソッド単位で細かくしたいなら、try〜catchでやってもいいし、スマートポインタを実装・流用してもいい。その際にunique_ptrを使いたいなら使えばいいというだけ。
伝わらないようなので少し細かく書いた。伝わるんだろうか・・・。
アムロの父親みたいな変な書き込み、リアルに遭遇するとやはり引く
>>457 質問したいレイヤと解決策のレイヤが合ってないだけw
自覚なさそうなところがますますテム・レイ感あるわ
お大事に
質問して複数人に回答してもらってるのに、ただ煽るだけの人に「自覚」とやらを問われてもねw
大好きなガンダムのたとえに勝手に満足して病んでてくれ
君にプログラミングは向いてない
今時特別な理由もなくnew演算子を使うC++プログラマは間違いなく無能だよ
理由はC++標準ライブラリを使用しない言語/処理系レベルの話をしていたから
ガンダムの記憶回路にとりつけるやつ好きなだけ作ってていいぞ
妄想の中でもニュータイプじゃない君にプログラミングは無理w
ガンダムに辿り着けずコロニー内で果てる
テンプレートを引数に取る関数で、
その入力として、vectorと配列を取るような関数で、いい書き方ってないですかね?
// vector向け
template<class T>int sum(const T& v, int size)
{
int acc = 0;
for(int i = 0 ; i < size ; i++){acc+=v[i];}
return acc;
}
内容同じなのに配列向けに
template<class T>int sum(const T* v, int size)
を作ってるけど一緒に表記できないかな、みたいな
>>466 ???
その定義で配列も受け取れるけど。
int main(void) {
int x[] = {1, 2, 3};
std::cout << sum(x, 3) << std::endl;
}
vectorならiteratorにしてもいいと思う
#include <vector>
#include <iostream>
using namespace std;
template<class T>int sum(const T begin, const T end) {
int acc = 0;
for(T i = begin; i != end; ++i){acc+=*i;}
return acc;
}
int main() {
int a[] = {1,2,3};
const size_t s = sizeof(a)/sizeof(a[0]);
vector<int> v(a, a + s);
cout << sum(a, a + s - 1) << endl;
cout << sum(v.begin(), v.begin() + (v.size() - 1)) << endl;
return 0;
}
ありがとうございます
>>467 頭のどこかでポインタにしないと取れないと思っていました
>>468 iteratorは馴染みがないのでそのコードで勉強させていただきます
>>462 ただのサンプルコードに今時とか無能とか・・
中で何が起きるか把握してない無能を量産しようとしないでくれ
本来はrangeの出番なんだがな
導入が遅れたばかりに……
#include <iostream>
#include <vector>
#include <array>
#include <string>
using namespace std;
template<typename Iter>
auto sum(Iter a, Iter b) {
using value_type = remove_const_t<remove_reference_t<decltype(*a)>>;
value_type acc {};
while (a != b) acc += *a++;
return acc;
}
int main() {
const int a[] { 1, 2, 3 };
vector<int> v { 4, 5, 6 };
array<double, 3> d { 3.5, 1.2, 0.9 };
const string s[] { "u", "n" "k", "o" };
cout << sum(begin(a), end(a)) << endl;
cout << sum(begin(v), end(v)) << endl;
cout << sum(begin(d), end(d)) << endl;
cout << sum(begin(s), end(s)) << endl;
return 0;
}
#include <iostream>
#include <vector>
#include <array>
#include <string>
#include <iterator>
using namespace std;
template<typename Iter>
auto sum(Iter a, Iter b) {
using value_type = typename iterator_traits<Iter>::value_type;
value_type acc {};
while (a != b) acc += *a++;
return acc;
}
int main() {
const int a[] { 1, 2, 3 };
vector<int> v { 4, 5, 6 };
array<double, 3> d { 3.5, 1.2, 0.9 };
const string s[] { "u", "n" "k", "o" };
cout << sum(begin(a), end(a)) << endl;
cout << sum(begin(v), end(v)) << endl;
cout << sum(begin(d), end(d)) << endl;
cout << sum(begin(s), end(s)) << endl;
return 0;
}
sumがunkoは独創的だと思うけど、戻り値の型はテンプレート引数でいいかもね
↓こんなコード書いてるんですが,もっとエレガントに代入できませんか?
a[0]=*ptr;
a[1]=*(ptr+1);
a[2]=*(ptr+2);
>>477 エレガントな回答ありがとうございます.
解決しました.
std::copy(ptr, ptr + 3, a);
僕はfor文のほうが好きです
>>479 >>481 こんなんもあるんですね.使わせてもらいます.ありがとうございました.
最近c++やり始めたんですが,ポインタが出てくるとギョッとします.
何に使いたいのか知らないけど、C++やめてRustの方がいいんじゃないの?
高速grepツールとして有名なripgrepはRustで作られてるからRustは優れた言語なのだろう、ぐらいなことは察せられるが
>>483 rustなんてプログラム初級者に勧めるなよ。
あんなの習熟した上級者向けの言語だわ。c++以上に初級者向け解説が無いのは致命的。
あと、Rustはスレ違いだからな。このコメにもレスするなよ。
>>485 C++の方が難しいよ
ポインタでギョッとするレベル=Cに抵抗があるなら、わざわざC++を使うよりはRustでいい
5chはコメとは言わない
お前がレスしなければ良かっただけ
Rust は良いアプローチだがどうしても記述量が多くなるから敬遠してる
>>486 ポインタは名札のメタファーを使った説明が確立しているけど、所有権、譲渡、借用、ライフタイムの初心者向け説明はクソみたいのしか無いだろ。そんなもん初級者に紹介するなよ。
スレ違いでわざわざ役立たずを紹介するやつは何を考えているんだろうかね?
>>488 はいはい、ID変えてご苦労さま
同じことだけど、生アドレス使うの得意でない言語の方が向いてるだろってだけ
C++は少なくともCをまともに使えるようになってから習得すべき
.hや.cpp以外からいじられたくない変数に対するインライン関数をパブリックに公開したいのですが、classを利用する以外にこのような事はできないのでしょうか?
staticや無名名前空間を利用するとcppファイルで利用できなくなりますしやはりclassを使えということでしょうか?
extern int value; //これは隠蔽したい
inline bool IsZero() { return value == 0; } //これはグローバルに利用してもらいたい
namespace {
extern int value; //これは隠蔽したい
}
inline bool IsZero() { return value == 0; } //これはグローバルに利用してもらいたい
>>489 ならc紹介しろよ。
スレ違いのクソを紹介するな。
もとい
namespace {
int value; //これは隠蔽したい
}
inline bool IsZero() { return value == 0; } //これはグローバルに利用してもらいたい
>>493 関数内にstatic変数持てなかったっけ?
>>494 連投失礼。
自身の関数内にあるstatic変数の参照を返す関数を用意するパターン無かったっけ?
>>492 ポインタに抵抗ある人にCを勧めるくらいならC++に近くて安全なRustを勧めるのが筋
見当違いな話をしてるだけだよ君は
valueの立ち位置が気になるが
extern(実行ファイル内で全部共通)するならinline関数のIsZeroが見えた時点でvalueも見えてないといけない
class hoge {
static int value;
public:
static bool IsZero() { return value == 0; }
};
inline bool IsZero() { hoge::IsZero(); }
int main() {
return IsZero();
}
>>493 ありがとうございます
ヘッダにそれを書いたとしてcppファイルからvalueを扱えるのでしょうか?
>>497 JavaやC#で言うところのprivate static intとして該当ヘッダ内&cppファイル内からは自由に扱え、それ以外からは見えなくさせたいという値です
JavaやC#でもそんなところに可視性の定義はない。
>>496 相手がなんでc++を使っているのかのニーズすら確認しないで何を独りよがりなことを言っているんだよ。
相手の目的を無視してスレ違いのツールを薦めるのはアホのやること。
Rustの伝道師はこんな低レベルなのかね。
あーうるせえ
C++スレでRust Rust連呼すんな
寒すぎんだよ
>>501 別に俺はRustの伝道師ではないが、
>>483で一言Rustを勧めたらIDをコロコロ変えながら文句を言ってくる人がいるだけ
ポインタが不得意でRustも使えない質問者ご本人様だと思ってる
>>493 試してないけどこんなのはどうかね。
#include <iostream>
#include <cstdlib>
class Accesser;
class Wall {
static int & val(){ static int v; return v; };
friend Accesser;
};
class Accesser {
public:
Accesser(){
int &v=Wall::val();
v=1;
}
~Accesser(){
std::cout << Wall::val()<< std::endl;
}
};
int main()
{
Accesser a;
std::cout << "Hello, Wandbox!" << std::endl;
}
inlineで書きたいらしいので、それだとコンパイル単位で値が変わっちゃうのでは?
>>505 インラインはどのみち無理じゃない?
関数内static変数は共通になる保証があったと思う。どこだか忘れたけど。
クラス内に実装を書くなどヘッダにあればどの道インラインだと思う
staticは静的に確保されるので、インライン展開されても同じシンボルを参照する
ちゃんと書いておくと、
>>490にもともとクラスを使わない指定があるので、どうかね?
という意味では前提を満たしてないと思う
クラスを使う最も素朴な例は
>>498に書いておいた
メモリ確保用途でvectorやstringつかい
ポインタアクセスすれば、new で確保するのと速度に大差ないとおもうんですが
実測すると10%〜くらいSTLつかうほうが速度低下するみたいなんですが
直メモリアクセスでも落ちるのはなぜなんでしょうか
その計測コード貼ってみ
多分メモリアクセスとは関係ない所で時間食ってる
>>509 ありがとうございます
やはりクラスを利用しないと実現無理そうなので、498のようなC#で言うところのstatic class的な形でやることにします
これです・・・
https://ideone.com/NKSCRi vector : 974.971 ms
new char : 921.191 ms
new int32 : 899.579 ms
こっちだと大差がついてるんですが
家のPCでもideone.comよりも差が付きます vector確保のほうが遅い
https://paiza.io/projects/9wWo36-bjTCL_S0WcGbaWA vector : 459.154 ms
new char : 184.758 ms
new int32 : 167.899 ms
自己解決しました
メモリ確保と解放部分を含めて計測してたのを
コピー部分のみの測定にしたらほぼ一緒になりました
https://paiza.io/projects/ge5iOWrzGu2E2PjogsRlUw vector : 219.947 ms
new char : 204.565 ms
new int32 : 214.644 ms
確保にかかってると思う?
一秒はさすがにないと思う。
何かおかしいな。
vector云々以前に、newバージョンも遅すぎると思う。
話にならないくらい。
i8008とかじゃないよね?
C++/CLIでstd::mutex使えないのなんでなん?
頑張ってWin32APIで代用する気力はあるけどわざわざ無効化されてる理由が知りたい
メモリ確保・解放と、メルセンヌツイスタを外して計測したら
今度はvectorのほうが圧倒的に早いんですが
https://ideone.com/rKv4qv vector : 237.55 ms
new int32 : 713.82 ms
計測時間は、ある程度の長さで、オンライン実行環境のタイムアウトにならないように
ループ回数を変更してるので
生ポインタにしたら同じ感じにならない?
unique_ptr<int32_t[]> p(new int32_t[2*size]);
int32_t* A = p.get();
mmcpy(A, size);
手動でループ回数変更とか馬鹿らしいからquick-bench.comとか使うのオススメ
overrunがある
std::make_uniqueを使え
サンプルコードだからと安易にnew演算子使う風潮やめたほうがいい
コールバックや別スレッドに渡すインスタンスの生成にのみnew演算子を使うべき
そういうことではなくunique_ptrを理解してから使えというだけ
バッドノウハウがいつまでたってもなくならない原因は入門者向けのサンプルコード
>>528 むしろ「理解してなくても使え」だよ
ナマポだってそうだ
サティアンとか金目とかじゃなくてな
実際に使って痛い目にあわないと
>>532 何でもそうだが、理解しないで使うからこういう問題が跡を絶たない
「理解してなくても使え」が何よりも悪い
>>534 それは違う
使わなければ理解できないよ
自身が初心者だった頃を思い出せないくらい耄碌したの?
お大事に
>>535 俺は初心者の頃から理解できていないものを何となく使うとかはしていない
それが何よりも悪いことを教わってきてるから
練習と本番を一緒くたにしてるな
まさに現場の癌だったと自白してるようなものだ
コロコロID変わる質問者兼劣悪回答者の荒らしで、そもそも勤務経験なさそう、と思ってるよ
>>536 現役離れてずいぶん経つの?
実務やってれば仕様書の文章があいまいで実際に動かさないと理解できないってことがいくらでもあるでしょ
「仕様書はない、ソースのみ(キリッ」という状況なんて普通なはずだが
上司が「お前は触るな」と言いたいのをオブラートに包んで「理解してから触れ」と言われたクチだろう
できないPGだった証拠
「理解してから使え」なんて、危なっかしい無能な人を開発現場から穏便に排除する時に使う言葉だよ
肩叩きされていたことに気づけないくらいに読解力が低い
「理解してから使え」
「はい、理解してきます」
「理解しました!今度こそ大丈夫です」←わかった気になってるが自分が何を分かっていないのかがわからない
普通は他人に迷惑かけることなく作業しろ、って言えば良いいんだけど、
察するに上司はそれまでの積み重ねで追放する気満々だったんじゃないかな
unique_ptrやshared_ptrは初心者でもコンパイラのエラーや警告に従うだけで安全にコードを書けるようになるからおススメだと思うよ
もちろん頓珍漢な警告メッセージを出力する不親切なコンパイラだとそうはいかないが
コールバックや別スレッドに渡すインスタンスの生成であっても
new演算子を使わねばならない必然性は無いので
ていうかnewしたブツを渡した先でdeteteさせる設計のは
newしたコードとdeleteするコードが同じCRTでないと危険なので
異なるプロジェクトの間でやるのは一般にアンチパターンなので
1. そもそも渡さない(利用するスレッドに生成させる
2. (どうしても渡したい場合は)コピーして渡す
3. オブジェクトの所有権を渡す側のスレッドが握って生存期間が利用期間を包含することを保証する
のどれかなので
少なくともウィンドーズのDLLはDllMain()を有する1本のプログラム同然なので
Ver.0.1のCRTをスタティックリンクしたDLLというものが作れてしまうので
Ver.0.2のCRTとリンクされるコードで生成したオブジェクトのポインタを渡せてしまうので
ActiveX系使ったことないんだろうなって容易に推測でける
しらそん
COMオブジェクトの中で異なるバージョンのCRTの混在が起きたら
同じことなんじゃないの
しらそん
アウトプロセスサーバが生成する
COMオブジェクトの中で異なるバージョンのCRTの混在が起きたら
同じことなんじゃないの
なので
>>549 そういうのをスマポでやれって話?
ヘッダで提供されるライブラリだからスマポもダメだと思うんだけど
>>552 急にCOM持ち出すのはおかしいだろ
>>553 ふつーCoTaskMemAllocじゃねえかな
sin関数に入れる時間変数の値が大きくなるにつれ誤差が増えていって困ってます
fmod関数を使ってもあまり効果が見られませんでした
処理時間をそれほどかけずに解決出来る良い案何かありますか?
sin関数に入れる値の目安は100万くらいです
100万をsin()しても、sin()は2π周期
doubleの精度15桁中の5桁以上を無駄にしている
sin()する用変数で毎回fmod(,2π)してもそこで誤差が貯まりそう
boost::multiprecisionとか?
出来るなら入れる数を作る時点で[0,2pi)に収まるように工夫する
それが無理なら多倍長浮動小数点数のライブラリ使うか自作するか
>>559 sinの引数に入れる値を浮動小数点数で少しずつ足しこむような処理をしているなら、やめて別の方法を考えろ
sinに時間を入れるのは次元がおかしい
っていうのは冗談で、質問者が何を問うてるのかわからん
sinにdoubleに収まるどんなデカい数を入れても精度は15桁くらい保証されるでしょ
>>560 > 100万をsin()しても、sin()は2π周期
> doubleの精度15桁中の5桁以上を無駄にしている
これもわけわかんねー
100万近いある数 x をsin()に入れるんでしょ?
x も sin(x) も上から15桁全部有効な桁でしょ
何が無駄になってるん?
>>562 こういう話ならわかる
sinのテイラー展開にxの大きな累乗が現れるからだよ
100万をバンバン累乗した級数で値域[-1,1]の関数計算してたら誤差まみれになるのは直感的に分かるだろ
>>563 318310 * pi が100万に近い2piの倍数
https://keisan.casio.jp/calculator で、14桁で計算する
2 * pi = 6.2831853071796
sin(6.2831853071796) = 1.3523E-14
318310 * pi = 1000000.3575642
sin(1000000.3575642) = 3.291426496E-8
わかった?
桁数同じだから、でかい数は細かい所が消えるのよ
>>565 現象としては確認できたが、理屈が分からない
>>564の言ってるようにテイラー展開の各項が激しくキャンセルし合って桁落ちするってこと?
>>564 のテイラー展開は疑問なんだけど
関数が[0,pi/2.)への押し込みもやってくれるんじゃないの
「桁数同じだから、でかい数は細かい所が消える」が理屈のつもりなんだけど…
sin(6.2831853) = -7.179586477E-9 だし、
sin(1000000.3575641670857) = -3.5E-14 だよ
sin()の結果に13桁の精度が欲しいなら、入力値に小数点以下13桁の精度が要るのよ
sin()は2piの周期関数だから
1000000の所に7桁も使っちゃうのはもったいないのよ
まだ小学校の算数で分かる誤差の話してんの?
>>560で話終わらん奴は小学校からやり直せよ
お前は小学校の国語からやり直せw
>> まだ「小学校の算数で分かる」誤差の話してんの?
誰も小学校で習うなんて言ってないぞ
俺小学4年生で級数展開したπの計算してたけど・・・
6年生でアセンブラと実数使ってたけど・・・
教える奴もよく分かってないからめちゃくちゃになってる
基本的には大きい数についても
>>563の考え「x も sin(x) も上から15桁全部有効な桁」で合ってる
sin() が 0 になるケースを考えてるからややこしいんだよ
sin() が 1 になるケース、つまり pi/2 の奇数倍で 100 万に近い数を入れてみろ
そしたらちゃんと 15 桁くらい 1 になるから
0 がややこしい理由は、仮数部が何であっても良いから
例えば 1e-20 は仮数部には1桁目からゴミが入っているが、倍精度ではゼロと見なす
>>576 お前は
>>560様の爪の垢を煎じて飲んでから、小学校をやり直せ
uniform_real_distribution の範囲を可変にしたいときってどうしたら良いでしょうか
0 から 1 までの実数を生成するようにしてそれを変数変換するべきですか
>>576 1になるケースでほぼ1になるのは、そこでの微分が0だからだよ
入力値がちょっとずれても結果への影響が小さいのよ
「x も上から15桁全部有効な桁」だからこそ、
1000000の所に7桁も使っちゃうのはもったいないのよ
sin(x)=0の所は微分が1または-1、入力のずれがそのまま出力に出る所
厳密な2πnと、doubleで表した有効桁数15桁の大体2πnに近い数字の差を計算すると、nが大きくなるほど差がデカくなってくるってだけの話じゃないの?
浮動小数点数は0から離れれば離れるほど目盛りが大きくなっていくのだから。
sinの実装がマクローリン級数展開でなくても起こる問題だと思うが。
おまえさん1人だろ
中学以後、いつ何を習うか知らないようだが
>1e-20 は仮数部には1桁目からゴミが入っているが、倍精度ではゼロと見なす
mjk、
IEEE754の2進数形式の倍精度浮動小数点表示は
仮数部がケチ表現の52 bit(実質53 bit)で
指数部は-1022〜+1023なのやぞ
1e-20とか1×2^(-60)かそこらなので無問題で53 bit(=15.9桁)の精度ェ、
>sin(x)=0の所は微分が1または-1、入力のずれがそのまま出力に出る所
x << 1のとき
sin(x) ≒ x
であることの見事な工学的応用、
よっしゃ、よっしゃ、おっちゃんがいいもん作ったろう
https://ideone.com/fjxKtS n=0,10000, 20000, 30000, ...,1000000 (とりあえず10000刻み)として、
2分探索でsin(x)=0となるxを、2π*n付近について調べてやった
そうやって求めたxをM_PIで割った結果はきっちり2*nになるから
sin(x)がxの周期関数だからといって必ずしもxの増大につれ誤差が増えるわけではないことがワカル
sin_valの値(=sin(x))が0に対して増えたり減ったりするのはマクローリン展開の近似多項式の係数を
結果があたりさわりのない誤差範囲でうろうろするように調整してあるんだろJK、
やっぱ
>>562というものが
>>559の誤差の真相なのではな
いか
>>588 結果見たけど、sin_valの値は、きっちり0から10000になったときに5桁精度悪化してるし、100000で6桁精度悪化してるのでは…?
>>589 パッと見だけど
>>565が答えじゃねえの
浮動小数点てのは文字通り小数点位置が異なる
数値が1付近と100万付近じゃ精度が異なるのは当たり前
精度を保つなら固定小数点使わないと
質問主が現れないからもう何議論しても無駄な気がする
ソースコードがあるわけでもないし
100万程度で誤差ヤバい言うぐらいだからfloatで計算してないか疑たくもなる
vectorでクラスへのポインタを持ってて、それを参照で受け取る関数を作るとき、クラスの変更を禁止したいんですが、どうすればいいですか?
例えば、
struct testclass{
int member;
};
というクラスがあって、
vector<testclass*>
を参照渡しで受け取る関数を作るとき、引数をconst vector<testclass*>& vecとしてもvec[0]->member =0みたいなクラスのメンバ変数の変更は関数の中で出来てしまうと思うのですが、そういうのをできないようにしたいです(testclassの変更が無いことを関数宣言で保証したいです)
何か良い方法ありますか?
vectorが1重であればtestclass const*const*を引数にすればいいとは思うのですが、vector<vector<testclass*>>のように多重vectorみたいな場合も作りたくて、そのときは関数を呼ぶ側で多重vectorから多重配列に変換するのは面倒なので、できればvectorではなく配列を使うというのはしたくないです
>>597 禁止しない
もしくはメンバ変数を非publicにしてgetter/setter
だから絶対値が1e-14とかより小さいかどうかだって
>>585なんかは全く理解してないようだが
ちなみにsinがゼロのとこは微分が1か-1でsinが1のとこは微分がゼロだから違うってのは、事実だが今回の事象の説明としては感覚的に過ぎるね
なぜならf(x) = xなる関数は微分は1だが f(1000000.3575642) は14桁正しいw
sinの挙動について理解したいなら実装に踏み込むしかないよ
あるいは
>>576あたりで思考停止しとくか
>>597 アクセスを厳密に禁止したいなら、配列操作のみ定義したラッパークラスを用意して渡したほうが良い。
クラス T のメンバ関数で自身のコピーを返す(つまり返り値の型が T)ものを考える
メンバ関数の修飾が && のときは std::move(*this) とかしたいけどこれはいちいち書かないとダメ?
普通は std::forward で統一できるが
*thisはxvalueではないからムブコンに渡したければstd::move()か(T&&)がいるね
>>598 ありがとうございます
ただ、
>メンバ変数を非publicにしてgetter/setter
これだと結局setterでメンバ変数を変更できてしまいますよね?
>>601 ありがとうございます、検討してみます
instance.field; が暗黙のうちに書き変わらないだけでも効果あるんだよ
void f(T&t){ t.clear();}
f(instance.field);
うっかりこんなことしたらヤバいし
const T& get_field() const;
を使っとけばコンパイル時エラーにしてくれる
>>597 冒頭の質問なら、参照渡し引数に
void f(const T&);
のようにconstつけとけばいい
>>597 まだ標準に入ってないけど、propagate_const使うとか
https://ideone.com/O8a0hn Packtpubが不安定になってるんだけど。
見れますか?
クラステンプレートについて、明示的実体化しておけば実装を.cppでもできるというのを知ったのですが、その場合、テンプレートでない普通のクラスと同じように
部分的にヘッダに実装を書いて、残りを.cppに書く、というのは正式な書き方として許されるでしょうか?
その昔、exportテンプレートというのがあってだな
class T;
class C {
public:
T t;
};
とあったとき
C c{T()};
と集成体初期化を行うと T のコンストラクタが1回だけ呼ばれます
メンバ t をカプセル化してコンストラクタを自分で用意するとどうやっても T のムーヴコンストラクタが余計に1回呼ばれてしまうと思ったのですが回避する方法はありますか?
>>613 直接的にはないけど
optionalとかvariantにあるin_placeコンストラクタと同じことをすればTのコンストラクタ呼び出しは一回で済みそう
>>597 配列の定義を vector<const testclass*> にすればよくない?
外では変更するけど関数内では変更しないことを明示したいんでしょ
関数の定義で
auto foo() -> void{}
みたいに書くの見かけたけどこのやり方何かメリットありますか?
あるね
auto s = std::string{"test"};
みたいな宣言とかも
戻り値の型を->の先に書いてあるだけだよ。
だからこれはvoid型の戻り値ね。
利点は引数からdecltype使って戻り値の型を指定できるくらいじゃない?
ラムダ式で返却値の型をどう書くかというのが後置スタイルを導入した直接の動機だと思う。
普通の関数で後置にするメリットがない場合であっても、
メリットがある場合とない場合で区別して使い分けるよりは全部を後置で一貫させたほうが綺麗だと思うこともあるだろ。
みずほが復旧をあきらめるとかどうみてもfukkyu
人がつくったものネットから持ってきて何個も組み合わせて合体させるとみずほみたいになるんだろうな
自分で作ってない部分はメンテしようがないからな
Windows serverにしたのが最大の間違い。
std::stringの大文字を全て小文字に変換するのってstd::transformより良いものあるの?
Windowsで文字列中の大文字を小文字に変換する_mbslwr()って今やランタイムで使えなくなってんだね、知らんかったわ
c++のexe → ライブラリA(c++のdll)
と
c++のcリンケージのdll → ライブラリA(c++のdll)
で
同じライブラリの同じ関数を呼び出してるのに
呼び出し元の形態によって挙動が変わるなんてこと有り得ますか?
ライブラリも呼び出し元も外部の同名のdllをリンクしているけれども
呼び出し元が参照しているdllの実体が別だったとか。
struct Vector2 { float x, y; };のような64bitで済んでしまうものの計算にSSE命令を使っても高速化は見込めないのでしょうか?
上記に対して_mm_mul_psを行うと上位2float分を余計に計算させることになってしまいますよね
>>603 deducing thisがC++23で入るね
>>632 余計に計算させるけど一命令で済むよ
ただし速度以外のデメリット出てくるけど
>>630 同じ関数というのが関数名と引数の数が同じというだけなら
extern "C" double sqrt(double x);
extern float sqrt(float x);
とから有り得る
pair<int, int> の first と second に、例えば座標と向きのような意味をもたせてるとします
このとき、using なんかを使って pair<int, int> x の第一要素と第二要素に x.pos、x.dir のようにアクセスする方法ってありますか?
>>636 C++ ではメンバ (のように見えるもの) を後から生やすことは出来ない。
auto& [x, y] = obj;
x = 100;
y = 100;
動くかは試してない
>>636 そういうあちこちで使う用途の、はっきり意味が決まった構造体は
pairやtupleに頼らない方が(大抵の場面では)便利だよ
その一箇所でしか使わないならpairでいいと思うけど
いくつかの要件を満たして "Tuple-like" であるようなクラスはタプルのように扱える仕組みがある。
タプルを多用途に使うよりは個別のクラスを作った上でタプルのインターフェイスを持たせるほうが
使いやすくなると思う。
みなさん御機嫌よう
このスレには何度も助けられているものです
再度お知恵を拝借したいです
任意のユーザー定義型のインスタンスhogeが、基底クラスbaseを継承しているか調べたいです。
この一例のみならtypeidで合致させればいいと思うのですが、実際は派生クラスが200くらいある予定です。
type-traitでインクルード出来るstd::is_base_ofで、RTTIを使い判定しようとしたのですが、typeidで取得できる型で合致させようとしたところ型情報が合いません……orz
どんな方法でもいいので何かいい方法がございましたらご教授いただければと思います。
class base{};
class driv:public base{};
class foo{};
//もしhogeがfoo型のインスタンスなら偽を、drivのインスタンスなら真を返したい関数
bool exHantei(){}
老眼なので Hantei が Hentai に見えた。
>>643 静的な型を判定するならこういうのでいけると思うが、
RTTI が出てくるってことは状況が違うのかな?
#include <iostream>
#include <type_traits>
class base{};
class driv : public base{};
class foo{};
template<class T>
bool exHantei(const T&){
return std::is_base_of<base, T>::value;
}
int main(void) {
driv hoge;
foo huga;
std::cout << exHantei(hoge) << std::endl;
std::cout << exHantei(huga) << std::endl;
}
dynamic_cast<base*>(hoge)がnullptrかどうかを見ろ
>>643 bool exHentai(){
return std::is_base_of_v<base, std::remove_reference_t<decltype(hoge)>>;
}
>>645 ありがとうございます。
ただ今これで動作確認はしました。
が本来は基底クラスのポインタに格納されているのです……
書き込む時に蛇足と思って省いてしまったのですが、実際は
class base{};
class driv:public base{};
class WantToFind:public driv{}
std::vector<base*> VecBasePtr;
void pusbak()
{
WantToFind f1;
VecBasePtr.push_back(&f1);
}
というようにベースポインタに押し込んで使っていて、exHantei()を使用する時にはベースとこのポインタを比較することになります。
今はちみつ餃子様のコードで動作確認をした後、自分のコード用に書き直したところ、ポインタから型を取得させる動作ができません(泣)
てっきりtypeidと同じ様に、exHantei(*VecBasePtr[0]);と*を付けてポインタの中身を外に出せば生のWantToFind型が出てくるかと思ったのですが……
思い通りの動作が出来ませんでした。
どうしてなんですかね、、、
デバッグモードで確認してもわからない
もちろんbaseに仮想関数は置いてあるので、RTTIで動作してくれるものと思っていましたが。
Templateの機序が違うのかな……?
だからdynamic_castで調べろって
そのための機能だから
>>649 ありがとうございます!!!
確認しましたところ自分の思っている動作が得られました☆*:.。. o(≧▽≦)o .。.:*☆
こんなに簡単に出来るとは、is_base_ofの使い所さんはどうなってしまうんだ。。。
レスへの返信を書きながら、自分でもコード確認やリファレンスを検索していたため、スレの確認が遅くなってしまい、多くの型と行き違いになってまいました。
返信をくださった方々には重ね重ねお礼申し上げます。
まだまだ弱輩者ですが、これからも生暖かい目で返信くださると幸いです。
皆さんありがとうございます!
>>648 動的型で継承関係を確かめるなら
>>646 が述べている通り dynamic_cast で実際に変換してみるのは手っ取り早い方法だと思う。
> 生のWantToFind型が出てくるかと思ったのですが……
「生の」ってなんやねん。
その場合の *VecBasePtr[0] の静的型はあくまで base だよ。
オブジェクトの base である部分 (サブオブジェクト) が取り出される。
いわゆるスライシング。
dynamic_castは知ってたはずなのに思い出さなかったというか思いつかなかった……
>>651 ありがとうございます。
自分はスライシングもちゃんと理解してないですね……
ポインタのメモリ確保サイズが一様に8バイト(4バイト)なので、基底型が派生型の型を丸ごと格納している(派生型のポインタを確保している)と理解していました。。。(*を付けると派生型が出てくる)
悪魔でも基底型なのですね?
キャストで受けるまでは基底型として扱われるので、型情報が合致しなかったのかな。
type_infoは、全く別の型を型合致に使うから*baseが有効なのかな。
dynamic_castって仮想関数テーブル必要じゃなかったっけ?
まぁいずれにせよ仮想関数テーブルでぐぐればそこらへんの理解が進むと思う
多分
用語って大事だよな
言葉遣いがおかしいの指摘されると逆ギレする
DQN気質なやつが残念ながら後を経たない
#include <cctype>
//#include <string>
template <typename F>
void test(F&& f){}
int main(){
test(std::isprint);
}
これ<string>を有効にするとcouldn't deduceになるんだけど
なんで?
コンパイラはMSYS2 g++ 10.3.0
<locale>のテンプレートが干渉してるっぽいことはわかった
これ、俺の落ち度なの?
ランタイムサポートが必要なC++言語機能ってRTTIやdynamic_cast、例外くらい?
そもそもランタイムサポートの定義をちゃんとしないとな・・・
RTTIも例外も標準C++の一部
それが使えないような設定は厳密には規格違反だし、それで高速化や効率化しますってのは各コンパイラの独自機能に過ぎない
dynamic initializationも裏で色々やってるね
とりあえずOSないところか、簡単な仕組みしかないところでC++で何か書いてみればいいよ
処理系が何をしてくれているのか分かる
658だけど、自己解決の報告。
テンプレートにしないで
void test(int(*f)(int)){}
にしたら<locale>のisprintが干渉しなくなった
最初の発想がいかんかった
isprintのテンプレート引数が決まらないからだろ
test(std::isprint<int>);
とかなら通ると思う
compiler explorerのarm g++ 10.3で確認した。ヘッダはlocaleにした。
#include <locale>
template <typename F>
void test(F&& f){}
int main(){
//test(std::isprint);
test(std::isprint<int>);
}
元のコードをなるべく変えずにだと
#include <string>
#include <cctype>
template <typename F>
void test(F&& f){}
int main(){
test(static_cast<int (*)(int)>(std::isprint));
}
※オーバーロードを選択させるべくキャストする
conceptでテンプレートテンプレート引数を弾いたりできないかとも思ったけど
SFINAEは関数の除外なので引数の候補を絞るのは無理だった
class A { static inline struct SubStruct { int value; } Field1; } //通常の構造体のスタティックメンバ変数はヘッダファイル、cppファイル共に実体は同じ
class A { static inline struct { int value; } Field1; } //無名構造体のスタティックメンバ変数はヘッダファイルとcppファイルとでそれぞれ別の実体が生成されアドレスが異なる
この挙動は仕様なのでしょうか?
今だと仮想関数とvariantとどっち使うのが主流ですか?
>>675 名前のない構造体には実体がなく外部リンケージを持たないのでそこに対するinline指定は無視されるってことでは?
分かりにくいけど仕様として矛盾してはいないと思う
>>675 「ヘッダファイルとcppファイルとでそれぞれ別の実体が生成されアドレスが異なる」という状態をどうやって観測しているの?
そんな挙動しないと思うんで、観測方法に間違いがありそう。
>>678 名前のない構造体もクラス型としては存在するし、それとは別に変数 A::Field1 は外部リンケージを持つよ。
https://timsong-cpp.github.io/cppwp/n4861/basic.link#5 > In addition, a member function, static data member, ..., has the same linkage, if any, as the name of the class of which it is a member.
>>678 あと仮にinline指定が無視されたとしても「別の実体が生成される」というような動作には繋がらないね。
>>599 アーハン?
doubleで表現可能な最小の数と1e-14の大小関係もわかんない人なんですかね、、、
>>593 その2π周期というのが厳密に2*M_PI周期であることの根拠は?
>>560の時点ではそれは示されていなかった
>>588で2*M_PI周期と言う実験結果がデタ
>>596 万能の一般論は無い(キリ
なぜなら、f(x)が0かどうかの判定をしたいとして、±|處を0とみなすべきなのかは
f(x)の精度に依存するから
ただし、
>>560式に f(x1) と f(x2) の等値判定なら
>>560式にやりうる
これは f(x1) - f(x2) のゼロ判定として
>>560式にやればよろっし
アンカーミスった;;;orz
s/
>>560/
>>588/g
>>681 O(1) の数値を使って計算してたら例えば 1e-15 以下の数値をゼロと見なすとかするより他ないでしょ
バカ?
知らなくて驚くかもしれないけどdoubleは1e-324も表せちまうんだ
>>681-687 まだやってたのか小学生・・・ID変えてご苦労様
何度も言ってるが
>>560でこの話は終了している
>>560 >100万をsin()しても、sin()は2π周期
>doubleの精度15桁中の5桁以上を無駄にしている
これよくわからん。
double sin(double x)の精度が±10E-10程度らしいことは
>>588の結果が示しているが
こっれはxが100万かどうかによらないことも結果が示してゐる
実装を見ないとわからんが、多分マクローリン展開の打ち切りによる誤差とみるべき
>>692 実装見てから言った方がいいよ。マクローリン展開というが、0を基準にマクローリン展開してるわけないだろ。
>>685 その方法は等値判定として一貫性が無いからNG
double x = 2.0;
double y = 2.0 + (10E-15) / 2.0;
assert(fabs(x - y) <= 10E-15); // pass. 10E-15基準で x == y とみなされる
assert(fabs(100 * x - 100.0 * y) <= 10E-15); // fail。 10E-15基準の下で 100 * x と 100.0 * y はイコールにならにあ
>>693 sin(x)の場合は|x|<<1においてsin(x) ≒ xなのでsin(x+a)を展開をする際のaを0にするのが妥当に思えまっする、
>>689-695 まだやってたのか小学生・・・ID変えてご苦労様
何度も言ってるが
>>560でこの話は終了している
>>678 挙動としては正にそんな感じですね
>>679 test.hにあるinline void 内でprintf("%p\n", Field1)、test.cppのvoid Func1内で同様の事をして確認しました
出力のみならず、そもそもヘッダのinline void内でField1に値をセットしたはずなのにソース内ではデフォルト値のままで動作が狂ったので上記のテストをして発覚した次第です
structを名前付きにするかしないかの一点だけで上記の結果が変わります
>>697 printf("%p\n", Field1)はレス間違いでprintf("%p\n", &Field1)で実験しています
#include<iostream>
struct A{static struct SubStruct{int value;} Field1;};
A::SubStruct A::Field1;
int main() {
std::cout << std::hex << &A::Field1 << std::endl;
return 0;
}
無名で実体の定義なんてできんのか?
ちなみに上の例は無名でない構造体で、実体の定義は
A::SubStruct A::Field1;
な
>>699 C++20だか17だかからはinlineをつける事で出来ます
#include<iostream>
struct A{static struct {int value;} Field1;};
decltype(A::Field1) A::Field1;
int main() {
std::cout << std::hex << &A::Field1 << std::endl;
return 0;
}
意外とやってみたら出来たw
>>700 A::SubStruct{}
で実体の「定義」ができる
&A::SubStruct{}
は実体がprvalueという理由でエラーだが
実体を定義できるか否かとは別問題だ
>>705 根本的に意思疎通できてないみたいだな
staticメンバA::Field1の実体定義だって
>>706 そのようだな
なぜstaticメンバが出てくるのか不明だ
>>703 確かに出来た
-std=c++17
付けたら実体定義なくても通った
コードはこんなのね(with -std=c++17)
#include<iostream>
struct A{static inline struct {int value;} Field1;};
int main() {
std::cout << std::hex << &A::Field1 << std::endl;
return 0;
}
実体は同じのを指すようで再現しなかったな。MakefileはちゃんとTAB入れてな。
cat >Makefile <<EOF
CXXFLAGS += -std=c++17
sample: main.o sub1.o sub2.o
\$(LINK.cc) \$? -o \$@
EOF
cat >main.cpp <<EOF
void sub1();
void sub2();
int main() {
sub1();
sub2();
return 0;
}
EOF
cat >sub1.cpp <<EOF
#include<iostream>
struct A{static inline struct {int value;} Field1;};
void sub1() {
std::cout << std::hex << &A::Field1 << std::endl;
}
EOF
cat >sub2.cpp <<EOF
#include<iostream>
struct A{static inline struct {int value;} Field1;};
void sub2() {
std::cout << std::hex << &A::Field1 << std::endl;
}
EOF
make
>>697-698 wandbox の gcc 11.1.0 でもやってみたけど、再現せず同じアドレスが出た。
https://wandbox.org/permlink/SSg6OZD97wmgR8kq コンパイラやバージョンやコンパイルオプションを合わせれば再現するのかね?
>>711 複数のオブジェクトファイルにしないと検証できないと思うよ
>>712 >>697の説明にあるtest.cppはtest.hをインクルードしてるんだろうからこの形でいいだろうと思った。
まぁやってみたけど、変わらないね。
https://wandbox.org/permlink/hfbakWmCF1i5stqr >>713 流石にヘッダファイルから何かが生成されることはないw
wandboxで複数オブジェクトファイルって処理系内部の作り次第になるし、
>>710でもやってみようかと思ったけど、3つは無理そうだね
>>711 検証頂いてるところ環境を明記しておらず申し訳ありません
Visual Studio 2022、C++20で発生している現象です
#include "test.h"
int main() //main.cpp
{
A::Initialize(); //printf("%p\n", &A::Field1);をするだけのstatic inline関数
A::Func1(); //printf("%p\n", &A::Field1);をするだけのstatic関数(__declspec(noinline)をし実装はtest.cpp)
}
struct名をつければInitializeの出力とFunc1の出力は一致、無名structにしたら不一致
本当に他は一切いじらずに名前の有無だけで変わります
現象を再現させる最小限のコードを全セット載せないと先には進まんて
始めからそうしてればこんなにいろいろ書かずに済んでいる
>>714 wandbox でも -v 追加で as が2つ test.cpp と prog.cc と別で走ってるのまでは見た。
>>716 MSVC のバグっぽいね。おとなしく名前つけて回避しつつ、できればバグ報告しとくのがいいんじゃない。
>>715 >>675で「無名構造体のスタティックメンバ変数はヘッダファイルとcppファイルとでそれぞれ別の実体が生成されアドレスが異なる」
と書いてあるが、ヘッダファイルから直接実体は生成されないよってこと
.cppなどのソースファイルからincludeされないとコンパイルしないから
(もちろんただのファイル名なのでコンパイラに直接ヘッダファイルをコンパイルせよと指定する事はできる)
つまりA::Field1に該当するシンボルが複数の.objに含まれた場合、同じになっているか=アドレスが同じになるか?
の検証でないと意味がない
>>718 それは昔からgccを使ってる人は知ってるけど、そういう話じゃない
明らかに不自然な位置にソースファイルを指定して無理矢理2個同時にコンパイルする上に、引用されて3個はできない
つまり想定された使い方ではないということ
おまけに処理系やそのバージョンを複数変えられることが比較的便利なwandboxで、処理系を変えると確認が必要になるやり方はどうかと言っただけ
まあ、分かってるとは思うんだが
とりあえず、710のコードでVS2019を調べた結果、再現は確認できた。
ただし、コンパイルオプション次第で現象が出たり出なかったりする。
VS2022でもないし、VSはコンパイルリンクオプションがデフォルトで大量に指定されてて確認が面倒なのでそれ以上は放棄した。
以下のコードではpermissive-オプションの有無で現象が再現したりしなかったりするが、デフォルト時だとその切替えで現象は変わらないので、一次原因ではないと思う。
保守できないような書き方して自分の仕事を守る。PGの当然の権利ですよね。
> main.cpp (
@echo void sub1^(^);
@echo void sub2^(^);
@echo int main^(^) {
@echo sub1^(^);
@echo sub2^(^);
@echo return 0;
@echo }
)
> sub1.cpp (
@echo #include^<iostream^>
@echo struct A { static inline struct { int value; } Field1; };
@echo void sub1^(^) {
@echo std::cout ^<^< std::hex ^<^< ^&A::Field1 ^<^< std::endl;
@echo }
)
> sub2.cpp (
@echo #include^<iostream^>
@echo struct A { static inline struct { int value; } Field1; };
@echo void sub2^(^) {
@echo std::cout ^<^< std::hex ^<^< ^&A::Field1 ^<^< std::endl;
@echo }
)
> sample.mak (
@echo CXXFLAGS = /MDd /EHsc /std:c^+^+17 /permissive-
@echo .cpp.obj:
@echo $^(CXX^) $^(CXXFLAGS^) /c $^<
@echo sample.exe: main.obj sub1.obj sub2.obj
@echo link /OUT:$@ $^*^*
)
nmake /f sample.mak
rem バッチファイルもnmakeもよく知りません。
>>723 そういうのはプロジェクトの方針だと思うので、ここで話す内容ではないと思うよ
>>723 >>727は何故だか文字が化けてたので一応書き直しとく。
改行と空白で違うのかよw もう知るかってレベルだけど、ありがと
とりあえず
>>710を載っけとく
https://wandbox.org/permlink/e8khwggKe00rtekJ C++11から、C++20までの変更点を解説した入門書を年末に買ったのだが(C++は書けるよ)、まだ読む気になれないw
「今更C++か、pythonでいいだろ」と悪魔が囁くw
c++cliについてネットに解説している情報あまり無いですが、まとまってるサイトとかないですかね。
めずらしい
変態に興味あるとは
VisualJ++とかワケワカだったぜw
1秒おきのタイマーでtmDraw()を呼んで右に伸びる四角を描くプログラムです。VSCでMFC未使用。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
OnPaint(hWnd);
break;
case WM_CREATE:
SetTimer(hWnd,1,1000,(TIMERPROC)NULL); //タイマー定義
break;
case WM_TIMER: //タイマー
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
tmDraw(hdc); //これを呼んで描画
EndPaint(hWnd, &ps);
}
break;
return 0;
}
static VOID tmDraw(HDC hDC)
{
SetDCPenColor(hDC, RGB(0x99, 0x66, 0x00)); //ここが呼ばれてるのは確認
SetDCBrushColor(hDC, RGB(0xFF, 0xCC, 0x00));
Rectangle(hDC, SIZE16(0, 0, cx++, 6)); //伸びる描画
}
最初の1回の描画はされます。タイマーでtmDraw()が呼ばれてるのは確認しています。
呼ばれて描画されてるはずなのですが、実際の画面は更新されず四角は伸びません。
windowサイズを手動で変えていくと四角は右に伸びていき更新されます。
タイマーでtmDraw()が呼ばれた時に描画だけでなく画面の更新もされるようにするにはどうすればよいですか?
WM_TIMERでBeginPaintはおかしいぞ
WM_PAINT専用なんだから
無効領域ないのにBeginPaintしたらあかん
[誘導] 続きはこっちでな
Win32API質問箱 Build127
http://2chb.net/r/tech/1639053176/ InvalidateRectとかGetDC〜ReleaseDCだっけ?
アップデートはマイクロソフトがやりたい時にやる
という基本理念を理解していないようだね
WM_TIMERでInvalidateRectしておくとWindowsがWM_PAINT呼んでくれるからそこで描画するんだっけ
そもそもこれCだろ…
WinMainから書く超基礎的コードをここで聞く頭がもうね
べつにアイドルループで描画してもいいんだよ
メッセージの処理さえ忘れずにピークしてこなせば
>>738 スレチなのは確かだが、いちいち見下して何がしたいんだお前
どこにでもいるんだよ
自分より下の者をいたぶることで
安心しようとするチンピラ気質なやつは
だってココ定期的に湧くじゃん
Windows使っててWin32APIの使い方聞いてくるC++ほとんど知らない自称天才のバカ
同じやつだよきっと
毎回Win32APIに誘導されてるってのにな
あー、言われれば確かにそんなの居たっけ・・
でもまぁ同一人物とは限らないんだし誘導して終わりでいんじゃね
たまに見当違いの初心者は入ってくるし(DirectXスレにDirectXランタイムのインスコの仕方聞きにきた猛者が居た
733 すいません、そっちのスレは知りませんでした
そちらで聞き直します
DirectXスレにDirectXランタイムのインスコの仕方聞くのはまだ仕方ない話
ドライバ固有の問題に当たっているなら専門家に聞いた方がいいだろう
自称天才のバカである確率の方が高いと思うし、高確率で単発IDで荒らすバカも同じだろうし、わざわざレスしてくるやつも同じだろうから、バカにはバカと言ってあげた方が親切
誘導ももう済んでるのに
どうしても喧嘩言葉を使いたくて沸いてくる
三下のそのまた下の家畜はいいのか
DirectXランタイムが許されるならWin32 APIだって許してあげなよ
製品名はVisual C++だし、既定の拡張子 .cpp なんだから Win32はC++ではなくCだって言ってもしょうがない
いかにも漏れは天才だが
さすがにWinMain()から書くようなバリバリWindowsアプリの質問はしないかなあ、、、
漏れの言ってることがまるで理解できない低レヴェル凡人の反発を招くことはあってもな
天才でも質問することあるんですね
回答者は超天才?
いかにも
私が超天才だが
ってどっかのハンコ貰いにいく人事のCMみたい
大学の課題でコンパイルエラーになるので教えてもらいないでしょうか
main.cppで、B<A> b; b.display(); のようにAを使っています。
g++ -Wall -std=c++17 -g -o test a.cpp main.cpp
undefined reference to `operator<<(ostream&, A const&)'
※コンストラクタなどの関数定義は省略してます。
■ a.h
class A {
public:
string m_str;
friend ostream & operator << (ostream &os, const A &a);
};
■ a.cpp
ostream & operator << (ostream &os, const A &a)
{
os << a.m_str << endl;
return os;
}
■ b.h
template <typename T>
class B
{
public:
void display(ostream &os = cout) const;
T m_dummy;
};
template <typename T>
void B<T>::display(ostream &os) const
{
os << m_dummy << endl; // ここが undefined referenceエラー
}
失礼、自己解決しました。
namespaceをa.hだけ括って、a.cppに入れ忘れましたw
下の★1を★2のように書きたいんだけど、どうやって書けばいいのか
教えてぇ
#include <iostream>
template <typename T>
auto Sum(T h)
{
return h;
}
template <typename Head,typename... Rests>
auto Sum(Head head,Rests... rests)
{
return head + Sum(rests...);
}
template<class F,class... Args>
auto
foo(F&& f,Args... args)
{
return f(args...);
}
int main( int argc, char *argv[] )
{
std::cout << foo(Sum<int,int,int>,1,2,3) << "\n";//★1
//std::cout << foo(Sum,1,2,3) << "\n"; //★2
}
>>753 そのようには書けない。 C++ では高階多相を許していない。
なんでも適当に済ますクセ
高級言語に慣れすぎの弊害
>>753 ・まず、Sumを多重定義にする必要性は特にないはず
・次に、fooが関数でSumが関数テンプレートの場合、
関数の実引数として具現しないテンプレートは渡せない
だからfooの代わりにstd::bindを使っても解決しない
・テンプレートテンプレート仮引数を使っても
クラステンプレートしか渡せず関数テンプレートは不可
こうなるとマクロくらいしか手がない
#define foo(func, ...) func(__VA_ARGS__)
戻り値のautoが決まらないってことでしょ?autoをdouble固定にしてReturnをなくせば通る
#include <iostream>
auto sum() {return 0;}
template<typename Head> auto sum(Head head) {return head;}
template<typename Head, typename... Tails> auto sum(Head head, Tails ...tails) {return head + sum(tails...);}
template<typename Return, typename... Args> Return wrap(Return (*f)(Args...), Args ...args) {return f(args...);}
int main( int argc, char *argv[] ) {
std::cout << sum(1,2.1) << std::endl;
std::cout << wrap(static_cast<double(*)(int,double)>(sum), 1,2.1) << std::endl;
std::cout << wrap(sum<int,double>, 1,2.1) << std::endl;
std::cout << wrap(sum, 1,2.1) << std::endl;
return 0;
}
// /usr/bin/g++ -fdiagnostics-color=always -g /home/user/cpp/autoreturn/sample.cpp -o /home/user/cpp/autoreturn/sample
// /home/user/cpp/autoreturn/sample.cpp: In function ‘int main(int, char**)’:
// /home/user/cpp/autoreturn/sample.cpp:10:29: error: no matching function for call to ‘wrap(<unresolved overloaded function type>, int, double)’
// 10 | std::cout << wrap(sum, 1,2.1) << std::endl;
// | ^
// /home/user/cpp/autoreturn/sample.cpp:5:52: note: candidate: ‘template<class Return, class ... Args> Return wrap(Return (*)(Args ...), Args ...)’
// 5 | template<typename Return, typename... Args> Return wrap(Return (*f)(Args...), Args ...args) {return f(args...);}
// | ^~~~
// /home/user/cpp/autoreturn/sample.cpp:5:52: note: template argument deduction/substitution failed:
// /home/user/cpp/autoreturn/sample.cpp:10:29: note: couldn’t deduce template parameter ‘Return’
// 10 | std::cout << wrap(sum, 1,2.1) << std::endl;
// | ^
>>753 auto Sum = [](auto head, auto... rests) { return (head + ... + rests); };
ラッパークラスを通せば似たようなことはできそう。
struct Wrapper_ {
constexpr static auto doit = [](auto... args) { return Sum(args...); };
} wrapper;
int main( int, char ** )
{
std::cout << foo(wrapper.doit,1,2,3) << "\n";
}
クラスは不要だった。
ラムダなら通るみたいだから、
>>758 みたいに元の関数をラムダで書くか、
auto wrapper = [](auto... args) { return Sum(args...); };
みたいなラッパー関数オブジェクト通すかってあたりで足りそう。
// 最初実験してたとき、ラムダ式にしただけだとエラー出てた気がしたんだけど、今やると問題なく通る…
>>757にラムダ入れた。
ラムダはオーバーロードできずC++17の畳み込み式が必須で引数なしが表現できないが、選択の手間がない。
#include <iostream>
auto sum() {return 0;}
template<typename Head> auto sum(Head head) {return head;}
template<typename Head, typename... Tails> auto sum(Head head, Tails ...tails) {return head + sum(tails...);}
template<typename Return, typename... Args> Return wrap(Return (*f)(Args...), Args ...args) {return f(args...);}
auto lambda_sum = [](auto head, auto ...tails) {return (head + ... + tails);}; // 追加
auto lambda_wrap = [](auto f, auto ...args) {return f(args...);}; // 追加
int main( int argc, char *argv[] ) {
std::cout << sum() << std::endl; // 追加
std::cout << sum(1) << std::endl; // 追加
std::cout << sum(1,2.1) << std::endl;
std::cout << wrap(static_cast<double(*)(int,double)>(sum), 1,2.1) << std::endl;
std::cout << wrap(sum<int,double>, 1,2.1) << std::endl;
// std::cout << wrap(sum, 1,2.1) << std::endl; // エラー
// lambda版追加
// std::cout << lambda_sum() << std::endl; // エラー
std::cout << lambda_sum(1) << std::endl; // 追加
std::cout << lambda_sum(1,2.1) << std::endl;
std::cout << lambda_wrap(static_cast<double(*)(int,double)>(sum), 1,2.1) << std::endl;
std::cout << lambda_wrap(static_cast<double(*)(int,double)>(lambda_sum), 1,2.1) << std::endl;
std::cout << lambda_wrap(sum<int,double>, 1,2.1) << std::endl;
// std::cout << lambda_wrap(lambda_sum<int,double>, 1,2.1) << std::endl; // not template
// std::cout << lambda_wrap(sum, 1,2.1) << std::endl; // エラー
std::cout << lambda_wrap(lambda_sum, 1,2.1) << std::endl;
return 0;
}
c++では
sz=120;
char dt[sz];
このように配列のサイズを変数の可変サイズで指定することはできないんですか?
これを実現する方法は何かありませんか?
自己解決しました
しかし dt[10][d] のように2次元以上はjavaのような動的変動はできないんですね
>>763 arrayという似たようなやつはあるが
基本的に作法が違う
コンストラクタ・テンプレートでテンプレート実引数を推定させず明示的に与えるのはどう書く?
struct some_class
{
template <class A> some_class(int) {}
};
int main()
{
some_class obj<void>(1); //error
}
>>768 コンストラクタには明示的に型引数を渡せない
ファイルサイズを取得しようとしていろいろサイトを参考にして次のようにしたのですが
std::filesystem::file_size(path)
filesystemのところに赤線が出て使用できません
これらは記述しています
#include <iostream>
#include <fstream>
#include <filesystem>
使っているのはCommunity 2019です
filesystemが使えないのはなぜでしょう?
>>771 filesystemが使えるのはC++17以降
プロジェクトの設定から言語バージョンをC++14(既定)->C++17に
filesystemは、できればC++20モードで使いたい
file_clockまわりがC++17ではgdgdだから
小文字に変換するプログラムです
string toLowerCase(const string& str)
{
string lower = str;
std::transform(lower.begin(), lower.end(), lower.begin(), std::tolower);
return lower;
}
実行するとstd::transform 一致するオーバーロードする関数が見つかりません、とか
6引数が必要です 4が設定されてます、とか出て
実行できません
これは何が問題なのでしょうか?
自分では他に定義してないんですがどこで定義されてるんでしょう
>>776 ちょうど
>>658 で同じような事例が出ている。
std::tolower は cctype ヘッダと locale ヘッダにそれぞれあって
locale ヘッダのほうが関数テンプレートだし二引数なのでこの場の都合に合わない。
なんらかの方法でどれを使うのか選択する必要があり、
たとえば static_cast などが使える。
ただ、
>>661 が提示しているようにデフォルト引数が追加される可能性があったりもするので
static_cast よりはラムダ式を経由するほうが安心できるスタイルかもね。
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
std::string toLowerCase(const std::string& str)
{
std::string lower;
std::transform(std::begin(str), std::end(str), std::back_inserter(lower), static_cast<int(*)(int)>(std::tolower));
return lower;
}
int main(void) {
std::cout << toLowerCase("abcDEfgHi") << std::endl;
}
template<yyy T>//yyyはコンセプト
requires !xxx<T>//xxxはコンセプト
void test(const T& a);//yyyのコンセプトを満たしxxxのコンセプトを満たさないものについて処理したい
C++20のコンセプトのrequires節って!使うと警告出るのでわざわざ否定用のコンセプト作成して対応してるんだけど、もっと簡単な仕組みない?
#define FOO() 1
#if FOO
...
#endif
と書いた場合FOOの後ろに()付けるの忘れてるのでコンパイルエラーになって欲しいんですが
実際はFOOは偽に評価されてるみたいです
何が起きてるんでしょうか?
>>785 #if の条件の部分ではマクロ展開できるものを全部展開したあとに知らない識別子が残ったら 0 と解釈する。
>>785 FOO に () が無いことで展開されず、マクロ展開後に残った識別子として 0 に置き換わってる。
https://timsong-cpp.github.io/cppwp/n4868/cpp.cond#11.sentence-1 > After all replacements ..., all remaining identifiers and keywords,
> except for true and false, are replaced with the pp-number 0, ...
#if defined(FOO)
...
#endif
Cの基本が出来てないくせにC++を使いこなせると思うなよ
>>786 >>787 ありがとうございます
このルールは知りませんでした
こういう馬鹿のためにコンパイラに無駄なルールが必要になるんだなと実感
馬鹿のためにわざわざプリプロセスで構文解析エラーを要求するとか馬鹿の極み
FOOが0になる根拠を与えていないだろ
関連付けられていないものが出てくるのがおかしいと思わないとしたらPG適性低いぞ
なんじゃそりゃ
>>799はC++規格委員会が死ね言うたら死ぬんか、
規格書にはなんでそうなっているのか(置換されずに残ったFOOをエラーではなく0にするのか)の理由が書かれていないが
#ifdef defined(FOO) && FOO
として現れる論理式「defined(FOO) && FOO」の解釈を簡単にやりたい(FOOが未定義の場合でも通常の式の解釈ルーチンで処理したい
的なしょーもない理由だったりして……
まつがえたorz
×: #ifdef defined(FOO) && FOO
○: #if defined(FOO) && FOO
>>801 唐突じゃないことを示したまで
事実関係をよく確認してからセンス無いとかドヤれってこと
理由はたぶん、規格化以前に存在した実装の動作を規格違反とするのはマズいとか、
その動作に依存して #if FOO としてる既存ソースをエラーとするわけにはいかなかったとか、
そんなところだろうと思う。
マズい動作として検出したければ警告は出せるんだし。
馬鹿がまだ騒いでるのかw
こういう変なコードとの対比w
$ g++ -x c++ - <<EOF
auto f = [](){return 2;};
#define f() 1
int main() {
auto i = f();
auto j = f;
return i + j();
}
EOF
$ ./a.out
$ echo $?
3
$
残った識別子を 0 に解釈する挙動は C89 からの仕様だから C89 の Rationale (根拠) を見たんだけど直接的な言及は見つからない。
https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0BxVCLS4f8Sg5NWZmM2NjZWEtYmExMS00Y2EzLWE3ZTMtNzFmYjYwYzBiOTIw&hl=en_US
ただ、既存のコードに差し障りがないようにということは明記してある (3.8.3) ので、
その時点でそういう挙動が支配的 (かつそれに依存するコードが多かった) のだろうとは察せられる。
規格ってのは統一を図るってのが第一の目的だけど無理な仕様でまとめちゃうと誰もその規格に従わないだけなんで、
現実にそれでやっているってのも (たとえ不格好でも) 十分な理由になるんだよ。
そう書かれるとC89っぽく書かないといかんのか?w
変更部分のみw
$ gcc -x c -std=c89 - <<EOF
int f(void){return 2;}
#define f() 1
int main(void) {
int i;
int (*j)();
i = f();
j = &f;
return i + (*j)();
}
EOF
CとC++の規格は既存コードへの忖度の塊で出来てるからな
万人の敵だったgets()を削除するのにどんだけ苦労してるのやら
>>806>>808
スレに乗っかったつもりにしては
#if f
〜
#endif
というのが含まれて無いようだが?
>>807 C++規格委員会は無罪なのかもしれんがじゃあなんでC89以前からそうで
そういう挙動が支配的になってしまう事態になってしまったのか、と考えると
やっぱプリプロセッサの最初の設計者がサボって
プリプロセッサ式の途中でのFOOの定義/未定義判定を
define(FOO)を導入する代わりに仕様の方を弄って簡単ハックしてしまったから
のでは……
天才は自力でなんとか出来るし、他人を信用しないことも多いから、基本的に質問とかする機会がない
アイデアレベルの話のみ
(σ゚ω゚)σゲッツ
stdioのバッファ使うヤツ殆ど失敗作
#define マクロは単純置換のやつと関数形式のやつがある
#define A(a,b)
A();A(1);A(1,2,3);A(1,);A(,2);A;
結構めちゃくちゃなことやってもプリプロセスはエラー吐かない
引数足りないとか関数形式マクロの括弧がないのは意図しない使い方だろうからエラーにしてもらいたい気持ちはわかるが
というか<<802で言及されてるけど#if UNDEFINEDも非推奨にしてほしいわ
#define DEBUG
#define DEBUG 1
#define DEBUG 0
//#define DEBUG (undefined)
これらの全部のケースに対応できてねーし
#if DEBUG+0 とか書けとでも?
俺のコードのg++やgccをcppに変えればプリプロセスの結果が出るよw オプション引数に-Eを付けても可w
別に不思議でも何でもない結果が表示されるw
$ cpp -x c++ - <<EOF
#define A(a,b) expanded
A();
A(1);
A(1,2,3);
A(1,);
A(,2);
A;
EOF
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
<stdin>:2:3: error: macro "A" requires 2 arguments, but only 1 given
<stdin>:1: note: macro "A" defined here
A;
<stdin>:3:4: error: macro "A" requires 2 arguments, but only 1 given
<stdin>:1: note: macro "A" defined here
A;
<stdin>:4:8: error: macro "A" passed 3 arguments, but takes just 2
<stdin>:1: note: macro "A" defined here
A;
expanded;
expanded;
A;
$
インクルードガード書くときも単に
#define FOO_HPP
とするのと
#define FOO_HPP 1
と1にするのがあるがどちらが良いとかあるんだろうか
後者の方がconstexpr if文などのC++の言語機能と組み合わせて使えるというメリットがありそうだが
今から新規に書くなら #pragma once 一択
>>818 私自身は前者にしてる。
インクルードしたことを示すためのフラグとしてのマクロが必要なら
(そういう事例に遭遇したことはないが) ガード用とは別にマクロ定義すると思う。
ガードのために定義したものをガード以外の目的で使うというのがちょっと汚く感じるから。
だけど分けちゃうと管理が二重になるのが嫌だと思う人もいるだろうし、
思想によるんじゃないの。
私は規格厨なので #pragma once は使わない。
まあ gcc と clang と msvc で使えるから事実上は問題にならないけど。
>>820 ありがとう
納得できる理由です
インクルードガード以外のフラグも同様にしてますか?
標準のNDEBUGのように
>>821 NDEBUG は「デバッグモードとそうでないモードを切り替える」というのがその用途なので
それに沿うと思ったら分けずに NDEBUG を使うことはあるよ。
でも「NDEBUG の用途は assert の有効・無効の切り替えなので他に使うべきでない」と認識している人がいてもおかしくない。
規格に書いてあるのはこの場合はこうだという規則だけなので
抽象的な部分での意味の捉え方は人によってかなり幅がある。
そのあたりは文脈を察して常識的判断でやっていくしかないし、
チームでやってるなら話し合うしかしょうがない。
このへんはそんなにスッパリと判断基準を設けられるようなもんではないと思う。
>>822 質問の意図がわかりにくくてすみません
自前でフラグ書くなら
>>818の前者と後者どちらを使うのかが知りたかった
>>824 基本的には前者。
フラグとしてのマクロで分岐するときは #if よりも #ifdef (または defined) を使うようにしてる。
マクロは型を付けられないからそうすることで ON/OFF のどちらかであって内容に意味はない
ことを明示してる感じを出したいと思ってる。
>>825 改めての回答ありがとうございます
こういう一見どちらでも良いものであっても裏の考えや意図が聞けて面白かったです
#pragma onceを標準に採用すればええのに
これだけ需要あるのに長年ずっと放置状態
何がそんなに問題なんだろう
現行仕様での理屈の立て方としては #include の効果でコードに一体化してから内容の解釈が始まるので
インクルードに干渉する余地がない。
現実にやってるんだから出来るのは間違いないんだけど理屈を根本から変えることになるし、
モジュールが上手くいけばどうでもよくなることに手間をかけたくないんじゃないかな。
シンボリックリンクで別のパスになってたりとか、同じ内容の別ファイルとか、ファイル名違う中身同じファイルとか、日付だけ違う別ディレクトリの同じ内容のファイルとか
そんなの考えたくないよなーw
名前と実体をどう対応付けるかは今でも処理系定義なのでそこらへんはあまり問題にならないと思う。
そこで#pragma onceはヘッダファイルそのものをインクルード済とみなすのではなくて
定義されている内容を定義済みと記憶するのが妥当な動作
なんだけど以下のような場合に困るという、
"a.h"
struct Foo {
"b.h"
int m_x;
double m_y;
};
"c.cpp"
#include "a.h"
#include "b.h"
やっぱモジュールにしたら同じような実装で完全な解決になるのだから待った方が、
現行の
#ifdef _FOO_H_
#define _FOO_H_
....
#endif
はヘッダファイルをインクルード済みか否かではなく
マクロ_FOO_H_が定義済みか否かを問題にしているのである意味モジュールに近い
#pragma onceは現行のマイクロソフトのやつはヘッダファイルをインクルード済みか否かを問題にしているので
何をもって同一のヘッダファイルとみなすのかという解釈の揺らぎの影響を受けてしまうまインクルードの挙動が、
>>830 だからどう転ぼうと中身で決められる昔ながらの方法の方が結果が明確ということw
ちなみにgccは
シンボリックリンク→ガード
同じ内容・日付・名前、別ディレクトリの別ファイル→ガード
同じ内容・名前、別日付、ディレクトリの別ファイル→インクルード
同じ内容・日付、別名前、ディレクトリの別ファイル→インクルード
みたい
でもCに代わってC++が広まったのはMSのおかげじゃん
ビット数多めのハッシュにしとけば
例えば衝突確率340澗分の1とかにできるよな
64bit osでポインタ型を4byteにするにはどうすればいいんですか?
8byteだとちょっと大きすぎる気がします
なぜ大きすぎると思ったのかが分からないが、64bitのアドレス空間を表すのに8 byteは必要だよ
64bit WindowsOSなら32bitアプリにすればok
例えば64bitの場合アドレスの上位4byteを一意に決めといて下位4byteを4byteの変数に格納しておくってやり方なんてはどうですか?
それで復元時には
(上位4byte << 32) & 下位4byteっていうふうに変換するってふうになると思うんですが
まず最初に上位4byteが一致した連続したメモリ領域から決まってメモリを確保するなんてことはできるのでしょうか?
必要なメモリをvector<X>で確保しておいて32bit以下のindex値でアクセスすることにすれば?
ポインタのサイズが大きすぎるなんて理由でやる人はいないと思うけど
long long ago... タイニー、スモール、コンパクト、ミディアム、ラージ、ヒュージつーのがあってだな
>>842 そうすることにします
ありがとうございました
関数ポインタかなんかが8バイトに収まってなくて混乱したことがあったっけ
昔は16bitポインタと32bitポインタをLPとPで使い分けてたって戦争で死んだおじいちゃんに聞いた
ウィンドーズならINT_PTR使っとけばおkオール無問題
C++の標準規格でどうなっているのかわ知らん
規格上は std::intptr_t というものがある。
ただし関数ポインタやメンバ関数ポインタを格納できるとは限らない。
また、省略可能 (optional) であると明記されているので無くても規格準拠たりうる。
関数ポインタ同士 (メンバ関数ポインタは含まない) はお互いに変換可能であり
元の型にキャストしたら元の値と等しくなることは保証されるので
任意の型の関数ポインタを格納したいのであれば void* や intptr_t を使うよりは
適当な型の関数ポインタに入れるほうが規格に沿う。
メンバ関数ポインタは型通りに扱う以外はほとんど何の保証もないのだけれど
無理に変換して扱いたい場合も特に思いつかないのでどうでもいい。
>>843 far/near を直接指定すれはすむ話、メモリモデルなんてどうでもいい
effective C++って現行のC++と比べてどのあたりが古いんですか?
代表的なところとかだけでも教えてくれると嬉しいです
出版1998年やんけ
こんなもん使うぐらいならC言語やった方がマシなレベル
>>854 一応第3版は原書が2005年に書かれています…
続編のeffective modern c++も古いけど、
こっちは隕石落下後の本だから読んでおいたほうがいいよ
隕石落下後ってなんすか?
あとC++の勉強するならこの本読め、みたいなのって他にもありますか?
2005年でも古いなあ
C++98, 03, 11(0x), 14, 17, 20 と5回バージョンアップあるし
そのたびに標準ライブラリが更新されてる
古い本で古い書き方しか知らないと慣れてきたころにイラつくことになるから最低でもC++11対応のやつがいい
今更auto_ptr使うなとか言われても何の役にも立たないからな
べつに使ってもいいんだよ
使い方さえ間違えなければ
仕様のバージョンは普通自分で選ぶもんじゃないので、古いことを知るのだって意味はある
逆にどの辺が古い、というのが分かってもあまり意味ない
いろんな範囲で一様乱数を次々と生成したいときってどうしますか?
uniform_int_distribution の範囲を次々と param で変える?
あるいは、妥協して剰余をとる形で範囲を変える?
あるいは、uniform_int_distribution を次々と生成して使い捨てる?
実測するべきなんでしょうが、どれがオーバーヘッドが少ないかというカンがありません
色々手はあるね
「いろんな範囲」の個数が決まっているならuniform_int_distributionの配列にするもよし
ランダムならparamもよし
次々と生成して使い捨て、つまりコンストラクタとデストラクタを都度実行するのは
俺はあんまりやりたくないが止めもしない
>>865 同じ範囲を何回も使うならその分distributionを用意する、そうでないならparamを変えていくのが良さそうに思います。が、たぶん実行時の差はほぼ無いです。
いちおう関数の定数を書き換えていくかメモリ上に予めたくさん用意するかの違いとして判断しました。
計算重いのは大抵は乱数生成の方だと思うので、速くしたいならそっちをとりかえたほうがいいと思います。
メルセンヌツイスターの売りの1つが速度がそんなに遅くない点だね
個人的にはこうやってみたりしてゐる、
/// 閉区間[0, ub]を値域とする一様乱数を生成する。
unsigned long genrand_int32_with_ub(unsigned long ub)
{
assert(0 < ub && ub < (unsigned long)UINT32_MAX);
const uint64_t F = (uint64_t)UINT32_MAX;
const uint64_t W = (uint64_t)ub + (uint64_t)1;
const uint64_t Q = F / W;
#ifndef NDEBUG
const uint64_t R = F - W * Q;
assert(Q > 0 && 0 <= R && R < W);
#endif
// 半開区間[0, (W+1)*Q)を値域とする一様乱数取得
const uint64_t WQ = W * Q;
uint64_t rndLTWQ;
do {
rndLTWQ = (uint64_t)genrand_int32();
//printf("rndLTWQ=0x%08x, Q=0x%016llu\n", rndLTWQ, Q);
} while (rndLTWQ >= WQ);
// Qで割る。
const uint64_t r = rndLTWQ / Q;
assert(0 <= r && r <= ub);
return (unsigned long)r;
}
>>869 分かり易い例として 0 から 9 の一様な乱数列を生成するものを考えてみればいい。
このとき 0 から 7 の値が必要だからといって 8 の余剰を取ったらどうなる?
8, 9 が 0, 1 になるから 0 と 1 の出現確率が他の倍になってしまうだろ。
生成される値の幅が必要な値の幅よりも十分に大きいなら
許容可能な誤差として無視できる場合も多いとは思うが
様々なパラメータが有りうる状況では検証しづらい。
>>872 呼出しのたびに必要な範囲が違うような Distribution が標準に無いという文脈
>>873 それもあるけれども、昔の擬似乱数列は絶望的なまでに下位桁がランダムではない、という事情をひきずっているのでは?まあ MT はそうじゃないけどね
>>873 そらもちろん、元がそんな狭い範囲ならだめでしょ
あとまあ昔のrand的には割ってかけるのが正しいというのはあるけどそれは別の話で
C++何の関係もない話で草
検証が必要ならすればいいだけ
要件すら不明で何もしてないのに質問するやつが馬鹿
>>876 > 元がそんな狭い範囲ならだめでしょ
逆に欲しい範囲が大きい場合でも同様。
この場合は様々な範囲が有りうるという想定なので、都合の悪い状況も考慮する必要がある。
任意の区間の乱数って、どうせはみ出した分をちょん切るんでしょ?
そんな短い周期の疑似乱数使ってないんじゃない?
端っこは気にしないと思うなあ
>>876 > そらもちろん、元がそんな狭い範囲ならだめでしょ
「分かり易い例」って書いてあるのも理解できないの?
一般論でいうと周期に余裕がない様な疑似乱数使うのが間違いなんだと思うけどね
そういうのを乱数知識ない奴が触らずに済むようにパッケージにしたのが<random>のdistributionなんだから素直に頼っとけよ
線形合同法とかなら値の範囲と周期が一致することもあるが、乱数の一般的性質というわけではない。
周期と値域は別だろ
たとえばマイナス一億と、プラス一億の2値をとる乱数とか
疑似乱数なんて今の値で次の値が決まるんだから周期も値も同じだろう
その値の一部を使ったらまあ見た目は減るだろうけど
値域: 出力される値の範囲
周期: そのまんま乱数の出力が1周するステップ数
内部状態かなんかとごちゃ混ぜになってない?
>>889 内部状態と結果を分離する方式だって当然あるよ。
メルセンヌツイスタのどでかい内部状態を毎回値として利用するわけないし、
乱数として利用できる性質になってない。
さすがにマジの最大値と最小値なんて誰も問題にしとらんやろ
>>892 その思い込みで「値域」と「内部状態の大きさ」をごっちゃにしてるから話がこじれてたんでしょ。
区別して。
端っこにゴミがあるよりは歯抜けが散らばってる方がいいというのは一理あるね
メンバー関数をテンプレートに出来たりしませんかね?
struct Sample{void func1(int i); void func2(int i);...}
template<typename T> void SampFunc(Sample& sample, int i){sample.T(i);}
みたいな
エラーはNo member named 'T' in ホゲホゲって感じですが
書き込んでから思いつきましたが直接やらずに
struct Caller1{void operator()(Sample& sample, int i){sample.func1(int i);}};
...
みたいなのを挟むべきですかねぇ
structの{}内にテンプレートの文全部入れてみ?
毎回 uniform_int_distribution のインスタンスを一時的に生成しては破壊するのを繰り返すのだけはありえんだろ
無意味なメモリのアロケーションありすぎ
#include <iostream>
using namespace std;
struct Sample{
void func1(int i) {cout << i << "," << __PRETTY_FUNCTION__ << endl;}
void func2(int i) {cout << i << "," << __PRETTY_FUNCTION__ << endl;}
};
template<typename T> void SampFunc(Sample& sample, int i, T member_func){
(sample.*member_func)(i);
}
int main() {
Sample s;
SampFunc(s, 1, &Sample::func1);
SampFunc(s, 2, &Sample::func2);
return 0;
}
doubleとfloatの配列を同じように関数の引数に渡して扱う方法ってありますか?
・処理部が複雑なので引数の型が違う関数2個は作りたくない
・IF関数として両方版を作ってそこから処理部を呼び出すみたいな構造は可能、ただし別型版の実体コピー配列などは作りたくない(配列が巨大な為)
考えてみたのが、
配列の値部分をvoid*配列で指したものと、type_infoを持ったクラスなり構造体なりを用意して、
処理部でtype_infoに応じてvoid*をキャスティング、という方法ですが、
どうにも汚いのでもっと綺麗なやり方あれば教えてください。
>>900 ふつーにテンプレートじゃね?
template <typename T> requires std::is_floating_point_v<T>
void func(T&& arg)
{
}
あとanyなんて手もあるけど
void func(std::any arg)
{
if(arg.type() == typeid(double)) { }
if(arg.type() == typeid(float)) { }
}
>>900 template<typename T, size_t size>
void f(T(&a)[size]){
}
>>903に便乗してC++20で以下のような書き方も
#include <concept>
template<std::floating_point T>
void func(T && a){}
>>900 まさかとは思うが
float f[2];
std::fill(std::begin(f), std::end(f), 0);
double d[2];
std::fill(std::begin(d), std::end(d), 0);
こんな基本はわかるんだよな?
ありがとうございます、テンプレート便利ですね。使わせていただきます。900
あるクラスのメンバ関数のデフォルト引数を同クラスのメンバ変数にすることって可能でしょうか
デフォルト引数をデータメンバにするってのは単にデフォルト引数の値をデータメンバに入れるって意味?
↓ こういうの?
struct foo {
int x;
void bar(int y=1) {
x=y;
}
};
こんな単純なことがわからないとも思えんし、なんか隠れた要件がありそうな気がするんやが
たぶん
struct S{
int field;
void f(int x=field){...}
};
ってのをやりたいんだろうけどな
あいにくC++のデフォルト引数は関数定義を見ただけで定数に決まるものしか受け付けられない
どうしても同等の処理をしたいならオーバーロードして転送するのが一番楽
void f(){f(field);}
> デフォルト引数は関数定義を見ただけで定数に決まるものしか受け付けられない
そうか?
int func()
{
int a;
std::cin >> a; //絶対に定数になり得ない
return a;
}
void test(int arg = func())
{
}
int main()
{
test(); //OK. もちろん入力待ちをする
}
>>915 デフォルト引数は関数を呼び出すときに補われたかのように動作する。
関数呼出しのたびに評価されるよ。
コードがないし状況不明で困ってる文面にも見えないからアレで十分
uniform_int_distributionって本質はIntTypeのペアを持った関数オブジェクトだから毎回生成したところで遅くはないはず
マルチスレッド環境用にジャンプって機能が疑似乱数にあるよな
「疑似乱数 ジャンプ」でぐぐると出てくる
状態持ってるのはエンジンの方
分布ごときにどんな怪獣ブラックボックスのイメージ持ってんだ
例外処理で、catchした後、どのクラスがthrowしたのかってわかりますか?
初心者質問ですみません。
ヘッダで定義したテンプレート特殊化の非推奨属性がヘッダ外で効いてないっぽいんですけど、
ヘッダ外でも非推奨としたい場合何か特殊な事をしないといけないとかありましたっけ?
例えば
.h
```
template <std::integral INT_TYPE>
struct int_auto
{
using type = auto_int_detail<std::is_signed_v<INT_TYPE>, sizeof(INT_TYPE)>::type;
};
template <>
struct [[deprecated("char type is not allowed")]] int_auto<char>
{
using type = auto_int_detail<std::is_signed_v<char>, sizeof(char)>::type;
};
template <std::integral T>
using int_auto_t = int_auto<T>::type;
int_auto_t<char> i_header; // これは非推奨
```
.cpp
```
int_auto_t<char> i_cpp; // これは非推奨じゃない
```
となっています。
MSVC++(v142)で言語標準準拠はstd:c++20です。
>>924 それ自体には発生元を特定する情報を持たないけど……。
どういう状況?
・ 例外的な状況から回復する必要があって発生源によって処理の切り替えが要る
・ プログラムの正常系が動くはずなのに何故か出てくる例外の元を特定したい (つまりデバッグ用途)
どちら?
>>926 大学でこういう課題を出されたのですが、全然いい方法がわからないです。
「あるクラスの例外だけをレポートするためにはどのような実装方法があるか」
>>927 ヒント。例外はクラス等なんでも投げられる。そしてクラスは継承できる。
それはどのクラスがthrowした、じゃなくて、どのクラスがthrowされた、の間違いだな
例外 c++で検索すれば答えはすぐ出てくるよ
>>916 >>917 嘘やんと思って試してみたらマジでいけるやんけ知らんかった
インスタンスフィールドまでは触れんかったが
>>928 なるほど。std::exceptionを継承した自作クラスを定義して、
それを投げるというこですね?
クラスメンバをforで回す方法はありますか?
例えばintのaとdoubleのbという2つのメンバを持つクラスがあったとして、
forループでクラス内のメンバ変数を全部加算したい、など。
イメージはこんな感じです。
double all = 0.0;
for (T member : this->allMember)
{
all += member;
}
for で回さないといけないほど多数のメンバー変数がある設計をまず見直すべき
動的にロードするのでなければ、自分で登録するか、ソースから解析するタイプのリフレクションライブラリを書くか探せばいい
じゃあこれもオススメではないがリフレクションベースで
https://www.rttr.org/ を使った例でも...
#include <iostream>
#include <rttr/registration>
using namespace rttr;
struct s{
int m1;
double m2;
};
RTTR_REGISTRATION {
registration::class_<s>("s").constructor<>()
.property("m1", &s::m1)
.property("m2", &s::m2);
}
template<typename T>
double sum(const T& o) {
type t = type::get<s>();
double sum = 0.;
for (auto& prop : t.get_properties()) {
sum += prop.get_value(o).to_double();
}
return sum;
}
int main() {
s o{1,1.1};
std::cout << sum(o) << std::endl;
return 0;
}
// 思いつきで聞いてるだけな気もするけどw
ちょっと修正
#include <iostream>
#include <rttr/registration>
using namespace rttr;
struct s{
int m1;
double m2;
};
RTTR_REGISTRATION {
registration::class_<s>("s").constructor<>()
.property("m1", &s::m1)
.property("m2", &s::m2);
}
template<typename T>
double sum(const T& o) {
double sum = 0.;
for (auto& prop : type::get<T>().get_properties()) {
sum += prop.get_value(o).to_double();
}
return sum;
}
int main() {
s o{1,1.1};
std::cout << sum(o) << std::endl;
return 0;
}
std::unique_ptr</*見切れる程長いクラス名*/> looongPtr{ std::make_unique</*見切れる程長いクラス名*/>(/*見切れる程多い引数*/) };
unique_ptrをメンバ変数にするときに最初のとこをautoに出来ないんですか?
typedef longlonglongtypename shorttypename;
auto ptr = std::make_unique<shorttypename>...
単なる○○できますか?に対して設計見直せとだけ言ってくるガイジなんなん
まず質問に答えた上でなら分からんでもないが
C++の業務ってことで入ったんだけどC++とは名ばかりのC言語バリバリのコードだった
C++11、いやせめてCじゃなくてC++を書こうとしようぜと思うんだけど世の中こんなんばっかなん?こういうケースほんっとに多くてさぁ
40代↑の人が書いてるC++の言語って大体ほぼCでうんざりする
偏見だけど同名の関数が並んでる以外Cとしてコンパイルできそうなイメージある
>>951 なんでそんなことになるんだろうな?
コンパイラを信用してないからか?
ワイは40代以上やけど C++ を使える状況であえて C 的なスタイルで書く気はしないわ。
だって単純に面倒くさいもの。
人事部の人がCとC++の見分けがつかなくて
会計上コンパイラ代に「C++」と書いてあったから
C++で募集かけてたんじゃね?
>>953 C++で通らないCは書きたくない、とは思いますね
>>951 ←こういう初心者にじゃあすべて作り直していいよ、と言うと何もできない。
無職の妄想からは何も生まれないのだよ。
自分は何かできるとでも言いたげだな
すべて作り直すということがどのくらいの工数かわかってないんだろ
>>958 俺もそう思う
現場の不平不満ばかりの意識高い系エンジニアさん多いよね
その現場を改善するわけでもなく文句いうだけ
高いスキルあるならそんな現場やめれば?
単価150万超えるようなとこなら周りにも高スキルな人がたくさんいるよ?
現場の文句言うだけの奴は結局その現場がお似合いのレベルなんだよ、っていつも思ってる
>>951 普通の職場ならコーディングスタンダードあるから勝手はできないだろ。
コーダーとライブラリアンで許可されている範囲も違うだろうし。
>>955 無職が言いそうなことだ。無能なブロジェクトリーダーはCプロジェクトをあっさりとC++化できる、
存在しないスーパープログラマを探し続けるがそんな奴はどこにもいない。
そんなスーパーPGがいたらATMはバグで止まらない。C++書ける奴はCをバカにしないよ。
正当な理由もなくスマポやSTLを嫌がった結果
生ポインタをガチャガチャいじくり回したスパゲティコード書いて
それが遅くて非効率でバグまみれリークだらけというのは非常によくあるけど
そういうCプログラマ様も敬わなきゃダメ?
そういうどうしょうもないのはヒソカに心の奥でバカにしていいし反面教示にすべし
80対20の法則は大事だし、動くコードを作ってから最適化をした方がいいって偉い人も言ってた気がする
リソース管理はとりあえずスマポを使うのが吉だと思ってます
自分で責任もって結合テストする覚悟があるんならいくらでもCからC++に置き換えていいと思うよ
とテストの基本がわかってないやつが言う
C++に動的な型宣言はないからな
効率ガーと言うが、CをC++に書き換えて高速化、省メモリ化するなんてむしろレアケース。
C++の隠れたコードが何をしてるか解ってないやつが
C++にしたら高速化した低速化したって言語のせいにするんだよ
こういうとき悲しいのはね
CもC++もたいして知りもしねえド素人のアマチュアが
想像と思い込みでもっていろいろレスつけてくること
噴飯ものだぞ?
c++書いてたとき何ちゃらストリームやらのファイル操作遅すぎてムリすぎて結局fopen使ったような…
まあ便利は便利なんだけど利便さ求めるならそもそもpythonとかに逃げますし
C++17未満?だとfilesystem使えなくてこんな簡単なことも出来ないのかと絶望した気もする
std::endlがフラッシュ兼ねてるのを知らずに使うとクソ遅くなる
Appleのcopland、Googleのandroid、MSのEdgeの失敗を見れば
予算と開発期間が十分にあれば解決すると思ってるならそれは間違いだと理解するだろう。
生ポインタをこねくり回す程度で脳みそのキャパが越えてるようじゃC++使ってもまともな実装なんてできない。
隠れたコードも何もC、C++はアセンブラの知識は必須だ。バイナリを読めるようになってから文句言え。
フムフムアセンブラが必須か…
https://godbolt.org/z/jq16j83We #include<vector>
using namespace std;
void f(char* dst, const char* src_start, const char* src_end) {
const char*s = src_start;
char*p = dst;
while (s != src_end) *p++ = *s++;
}
template<typename Dst, typename Src>
void f2(Dst dst, Src src_start, Src src_end) {
auto s = src_start;
auto p = dst;
while (s != src_end) *p++ = *s++;
}
void hoge() {
vector<char> dst(1024), src(1024);
f(dst.data(), src.data(), src.data() + src.size());
f2(src.begin(), dst.begin(), dst.end());
}
これってどうしてhoge側だとSIMD使わないの?
C++コードでSIMD使わせるにはどうしたらいい?
hoge側でどうSIMD使えって言いたいの?
inlineとかだったらしばくぞ
intrinsicは(inline)assemblerとほぼ同じなので、C#でしか使ったことないな
アセンブラなどの理解は「低レイヤを知りたい人向けのCコンパイラ作成入門」が結構勉強になったんですが、バイナリは何で勉強すればいいですかね?
>>985 キャッシュメモリのアレで遅くなるやつか?
さぁ?・・・callしたり判定用コードやサイズ計算とかオーバーヘッドがあるからじゃね?知らんw
CADソフトCANDYの作者の発言。
>数年前に,私の会社で組み込み機器向けのプロジェクトで,C++コンパイラが安定して動かないので
>Cでプログラムを書くように私が指示したケースがあったのだが,
>何人かのエンジニアが「今さらCなんかでプログラムを書けませんよ。
>クラスを使えなければスパゲッティコードになってしまいます」と猛反対をしてきた。
■ 第4回 オブジェクト指向の本質
https://gihyo.jp/lifestyle/serial/01/software_is_beautiful/0004 別のインタビューと補完すると、そのときC++の標準ライブラリ的なブツを著者が
C言語でババーっと書いて仕事させたという話だったはず(記憶モード
ちょっどこの昭和カヨ?!
組み込み機器用のCPUって特殊なんで、コンパイラが安定しないなんてよくある話
オブジェクト指向のメリットの本質についての話なので、可能/不可能が実装言語に依存しないというのもよくある話(楽かどうかは別)
別に昭和でも平成でも令和でも変わってないけど、
>>991に伝わってないのは確か
GTKのGObjectはCでオブジェクト指向を実現している訳だけど
(ただし学習コストが低いとは言えないと思う)
そんなん言ったらX Window SystemもC言語でオブジェクト指向しているらしい
らしい(伝聞
当たり前だけどアセンブラでもオブジェクト指向はできるし還暦の爺さん(とは言ってもなかなかの人ではある)が10年以上前に書いた記事だしまじで何を言いたいのかよくわからん
分からん分からん言うのは誰でも出来るし、どんな初心者でも何に対してもそう言える
なので、具体的に分からん部分を指摘できない人は初心者か、荒らしだと思ってる
>当たり前だけどアセンブラでもオブジェクト指向はできるし
ちょっカプセル化(シンボルの隠蔽)にやや手間がかかるし
オブジェクトをスタックにのコピーして返すのにもさらに手間がかかるし、
コンストラやデストラの呼び出しの保証や継承関係のチェックについて処理系のサポートが一切無いし、
やんけ;;;
そういうオブジェクト指向のプログラミングパラダイムにおいて裏で当然働くべき処理が
プログラマーが手間をかけ注意を振り向け続けないと実現されないというのはオブジェクト指向しているうちに入らないのでは……
brainfuckでもオブジェクト指向でプログラミングできるんやで
-curl
lud20250124193840ncaこのスレへの固定リンク: http://5chb.net/r/tech/1636969758/
ヒント:5chスレのurlに http://xxxx.5chb.net/xxxx のようにbを入れるだけでここでスレ保存、閲覧できます。
TOPへ TOPへ
全掲示板一覧 この掲示板へ 人気スレ |
Youtube 動画
>50
>100
>200
>300
>500
>1000枚
新着画像
↓「C++相談室 part158 YouTube動画>1本 ->画像>3枚 」を見た人も見ています:
・C++相談室 part154
・C++相談室 part153
・C++相談室 part152
・C++相談室 part133
・C++相談室 part137
・自営業 悩みごと相談室 16
・C#, C♯, C#相談室 Part93
・自営業 悩みごと相談室 52
・自営業 悩みごと相談室 48
・自営業 悩みごと相談室 45
・C#, C♯, C#相談室 Part95
・アパート経営なんでも相談室【135号室】
・【真剣相談】大阪市営住宅の浴室給湯器設置
・シーバスなんでも相談室 17©3ch.net
・【ハゲ】髪の毛の悩み相談室 in DQO【彡⌒ミ】
・アパートマンション経営なんでも相談室【152号室】
・アパートマンション経営なんでも相談室【137号室】
・アパートマンション経営なんでも相談室【150号室】
・アパートマンション経営なんでも相談室【151号室】
・【皇室】小室圭さん、「解決済み」声明文 宮内庁に事前相談なし
・【皇室】眞子内親王殿下がお気持ち表明「結婚に向けて家族とも相談しながら進んでまいりたい」★9 [記憶たどり。★]
・【名古屋】いじめ相談も「報復」恐れ学校側は直接指導せず…中1女子が下校後に自殺 2月から教室に行かず別室で授業 [ばーど★]
・東京の梅毒感染者2400人超で過去最多ペースで増加…内訳は男性7割女性3割 無料・匿名の検査相談室を新宿や多摩地域に設置 ★2 [首都圏の虎★]
・【ガルパン】マライ・メントラインの勝手にお悩み相談室「困っています。全力で『ガルパン』を推すために私は何を為すべきでしょう」 [鳥獣戯画★]
・室井佑月「(日の丸マスク)謝罪し訂正したのだけど、お詫びしろ、という意見…。弁護士に相談…」 ネット「被害者面」「実害出てるけど? [Felis silvestris catus★]
・荒らし相談室
・エイブル相談室
・不登校相談室5
・ハゲミン相談室
・船乗りなんでも相談室・10
・川瀬いにみの人生相談室
・シーバスなんでも相談室92
・シーバスなんでも相談室85
・シーバスなんでも相談室70
・シーバスなんでも相談室62
・精神障害者の人生相談室
・シーバスなんでも相談室71
・アダルトの何でも相談室
・シーバスなんでも相談室36
・シーバスなんでも相談室39
・◎蟹座の子育て相談室◎
・Dr林のこころと脳の相談室17
・病巣院クルリのお悩み相談室
・綾子88kg♪の恋愛何でも相談室★
・必ず誰かがなんたら相談室 Part.3
・苔 コケ 初心者なんでも相談室-4回目
・明るい悩み相談室 [無断転載禁止]
・初心者の為のボート相談室 Part1
・レポ神のピンサロ相談室 ©bbspink.com
・鍼灸マッサージ質問相談室パート11
・鍼灸マッサージ質問相談室パート17
・【本家】船乗りなんでも相談室 22【内航船】
・鍼灸マッサージ質問相談室パート16
・【本家】船乗り何でも相談室 20【本元】
・【ノーワッチョイ】船乗りなんでも相談室 27【内航船】
・初心者優先デジタル一眼質問・購入相談室 53
・(・3・) ぼるじょあの卓上相談室(・3・)
・08070507787 ★ 真智宇 先生の悩み相談室
・【スノーボード】初級者なんでも相談室 ☆6
・初心者優先デジタル一眼質問・購入相談室 157
・初心者優先デジタル一眼質問・購入相談室 103
・初心者優先デジタル一眼質問・購入相談室 109
・初心者優先デジタル一眼質問・購入相談室 101
05:38:43 up 11 days, 6:42, 2 users, load average: 14.01, 12.48, 11.43
in 4.6062610149384 sec
@2.9802708625793@0b7 on 012419
|