X



C++相談室 part162
レス数が1000を超えています。これ以上書き込みはできません。
0001sage (ワッチョイ fbf0-ofdD)
垢版 |
2022/10/31(月) 14:29:35.57ID:J5sgTSch0
!extend:checked:vvvvv:1000:512
!extend:checked:vvvvv:1000:512
↑同じ内容を3行貼り付けること

次スレは>>980が立てること
無理なら細かく安価指定

※前スレ
C++相談室 part161
https://mevius.5ch.net/test/read.cgi/tech/1653135809/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
0003デフォルトの名無しさん (スップ Sd73-OvbD)
垢版 |
2022/11/01(火) 07:31:00.75ID:8mAHYLmxd
寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処藪ら柑子の藪柑子パイポパイポ パイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助
0005デフォルトの名無しさん (ワッチョイ 79c2-iO6U)
垢版 |
2022/11/03(木) 09:15:40.37ID:AvIGv7Uk0
template <template<class...> class T>
struct is_map : std::false_type { };

template<> struct is_map<std::map> : std::true_type { };
template<> struct is_map<std::multimap> : std::true_type { };
template<> struct is_map<std::unordered_map> : std::true_type { };
template<> struct is_map<std::unordered_multimap> : std::true_type { };

template <template<class...> class T>
concept map_t = is_map<T>::value;

template <template<class...> map_t MAP, class... ARGS> //C3339
void test(MAP<ARGS...>&&) {}

うーん、困った
どうしよう。。。
0011はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7b3e-Tk+f)
垢版 |
2022/11/03(木) 22:28:39.04ID:b1nVlp4p0
>>10
コンパイラが無限のリソースを使えるわけじゃないから制限があってもいいし、
わかっている制限は文書化するべきということになっている。
https://timsong-cpp.github.io/cppwp/n3337/implimits

言語仕様の側でもどの程度まで処理すべきかという最低限の数値は与えていて
この場合だと
Recursively nested template instantiations [1024].
ってのが当てはまる。
あくまでもガイドラインなのでこれ以下に制限された処理系がないとは言えないんだけど、
1024 が提示されているところで 100 やそこらに制限するような処理系はたぶんあんまりないとは期待できると思う。
0015デフォルトの名無しさん (ワッチョイ 79c2-iO6U)
垢版 |
2022/11/04(金) 16:29:55.40ID:MccBwaps0
つーかよ
俺5だけど、あの程度のことで
8みたいなこと言われたのずっこけてる

別に無駄に複雑化はしてないし裏技も使ってない
当たり前の書き方で目的を素直に書いてるだけなのに

一次テンプレートと特殊化でis_系のクエリーを作って
それでコンセプト作って使おうとしただけだぜ?
何があかんの?

テンプレートテンプレート仮引数がわからんだけじゃないのかって邪推しちまいそう
0019はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7b3e-Tk+f)
垢版 |
2022/11/04(金) 19:44:51.78ID:lXYNWX4U0
制限はあくまでも「深さ」であって「回数」ではないので上手いこと変形するのも技の内だったんだよな……。
遊びでやるならきつめの制限も楽しいんだけどね。
0027デフォルトの名無しさん (ササクッテロロ Sp79-uppo)
垢版 |
2022/11/09(水) 10:37:27.83ID:uQIa4jnTp
質問です
マネージドとかアンマネージドとかMSの呪いですか?
0028デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/09(水) 11:23:16.37ID:GzNJb2MKM
プログラミング言語 C++ [第四版]
BJARNE STROUSTRUP, 柴田望洋 訳
「第四章 C++を探検しよう:コンテナとアルゴリズム」のp.102-103
に以下の様なコードが有るのですが、phone_book = の右側の初期化子(?)
の部分をコンパイラ内部でどのように翻訳(解釈)していくのかの厳密な詳細が
分かりませんので、どなたか教えてもらえませんか。
struct Entry {
 string name;
 int number;
};
vector<Entty> phone_book = {
 {"David Hyme",123456},
 {"Karl Popper",234567},
 {"Bertrand Arthur William Russell",2345678}
};
前提として、クラステンプレート vector<T> には、以下のような
「初期化子並びコンストラクタ」があることとします。
template <class T, class Alloc = allocator<T>>
class vector {
・・・
 // 初期化子並びコンストラクタ :
 vector( std::initializer_list<T> a );
・・・
}
ここで問題となるのは、以下のどちらの方法で解釈されているかということです。
[続く]
0029デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/09(水) 11:24:30.65ID:GzNJb2MKM
>>28
[続き]
(1) {・・・}を翻訳した後に、コンストラクタを探す。

phone_book = の右側の部分は、コンパイラ内部で、いったん
std::initializer_list<UUU>型のオブジェクトに直される
(なお、UUU がどんな型かは不明)。
vector<Entry>クラスの中にたまたま「初期化子並びコンストラクタ」
vector( std::initializer_list<Entry> )を見つけて
initializer_list<UUU>をinitializer_list<Entry>に変換してから、
vector( std::initializer_list<Entry> )に渡す。

(2) コンストラクタを見つけた後に、{・・・}を翻訳する。

vector<Entty>クラスの中にコンストラクタを探して、
vector( std::initializer_list<Entry> ) があることを発見。
このコンストラクタの引数が、std::initializer_list<Entry>であることから、
phone_book = の右側の部分を、std::initializer_list<Entry> だと
思って、コンパイル(意味論的に解釈)する。

# 推定ですが、(1)だと上手く行かない気がします。
[続く]
0030デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/09(水) 11:25:24.81ID:GzNJb2MKM
>>29
[続き]
[自分なりに調べたこと]
[A] p.293. 11.3 「並び」によれば、
{}構文は、名前付き変数を初期化する(§6.3.5.2)だけでなく、
(すべてではないものの)多くの箇所で式として利用できる。その構文は、
以下の二種類だ:
[1] T{...}:型で修飾された形式。"T型のオブジェクトを作成してT{...}で初期化
する"ことを意味する。§11.3.2。
[2] {...}: 型で修飾されていない形式。利用している文脈に基いて型を
決定できる必要がある。§11.3.3。
# auto以外では{}内の要素の型は推論に利用「されない」」らしい。p.297

[B] p.327によると、
「{}で囲んだ並びは、以下のものに対する引数として利用できる:
[1] std::initializer_list<T>型。並びの中の要素の値は、
  暗黙理にTへと変換される。
[2] 並びの中に与えられている値で初期化可能な型
[3] Tの配列への参照。並びの中の要素の値は、暗黙裡にTへと変換される。
0031デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/09(水) 16:50:18.10ID:XEaxVtCg0
大体わかってそうだけど
{…}をinitializer_list<Entry>として解釈しようと試みる→中身の{"David Hyme",123456}とかをEntry型に暗黙変換しようと試みる→全部変換できれば成功
Entryがexplicit Entry(string, int);を持ってると暗黙変換できなくて失敗するようになる
0032デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 00:59:56.86ID:8S99EFBAM
>>31
vector<T>クラスのコンストラクタに、initializer_list<T> 以外の引数を
持つものが存在していた場合、どういう優先順位でコンストラクタが選ばれて
いくのでしょうか。
コンパイラは、最初に初期化子の {・・・} の部分のカンマで区切られた中身の
個数を数えてから、その個数によってどのコンストラクタを選ぶかを決めますか?
0033デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 01:07:30.02ID:8S99EFBAM
>>32
仮にそうだとすると、コンパイラの内部では、
1. vector<Entty> phone_book の宣言の型である vector<Entty>を把握。
2. = の右側の初期化子の部分の{}の中の個数など大まかな特徴を掴む。
3. 2の特徴に基いて最適なvector<Entry>のコンストラクタを探す。
4. = の右側の部分を3.のコンストラクタに基いて解釈/変換する。
という少なくとも4段階の工程を得ていることになりそうですが、随分と
特殊な解釈の仕方ですね。
通常の式ならば、このように「いったりきたり」はしないものですが。
0034デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/10(木) 07:25:48.25ID:JLZuLXt50
そこは通常のオーバーロード解決と同じだけど何が気に食わないの?
f(int)とf(int,int)があってf(1,2)を解決するときに「先に引数が2個あることをチェックするなんてインチキだ!」って発狂されても
0035デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 12:27:18.30ID:Ma0XsUW1M
>>34
しかし、その場合、どの関数を呼び出すかが決定されてから後に、パラメータ(実引数)
の意味解釈は変化せず、実引数の解釈は同じで、必要あらば関数の仮引数へとcastされるだけです。
ところが、今回の初期化子の場合は、実引数の大体の様子が調査された後に、
どのコンストラクタを使うかが決定。コンストラクタが決定された後に、実引数の
意味解釈まで変わります。
0036デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 12:30:32.91ID:Ma0XsUW1M
>>35
[補足]
前半の通常の関数の場合、コンパイラの内部で隠れてcastされるという訳ではなく、
必要あらばちゃんとcastに必要な「変換関数」が呼び出されることまで決まって
おり、マシン語レベルで変換関数を呼び出だすcall文が生成され、その中で
変換に必要なマシン語の列が実行されます。
ところが、後半の初期化子の場合、その変換関数が呼び出されない可能性が高い
です。なぜなら、変換ではなく、最初からのコンストとラクタの仮引数の
型に合わせて意味解釈されて、いきなりその型としてコンパイルされるためです。
0038デフォルトの名無しさん (エムゾネ FFb2-DoDL)
垢版 |
2022/11/10(木) 12:36:36.70ID:43j6CzLZF
これvector<Entry>に
std::array<Entry,3>とか
std::tuple<std::pair<const char*, int>, std::pair<const char*, int>, std::pair<const char*, int>>
とか受け取るコンストラクタが追加されてたらまた話変わったりするよね

一応全部合法的に受け取れるはずだから、
コンパイラはどう解決するべきかってのを >>28 は聞きたいんだと思う
0039デフォルトの名無しさん (スッップ Sdb2-DoDL)
垢版 |
2022/11/10(木) 12:40:22.21ID:IDnNuz1Ud
なんか書き込んでからどっちもコンパイル通らないような気がしてきた
忘れてくれ
0041デフォルトの名無しさん (スプッッ Sd12-oy7h)
垢版 |
2022/11/10(木) 13:24:31.23ID:WlLaCVUwd
初期化子をコンストラクタのオーバーロード候補(静的に決まる)にそれぞれ適合させてみて、どれもダメならエラー、複数当てはまるなら優先度に従って1個に絞れたらそれを選択、曖昧ならエラー

初期化子や優先度の複雑怪奇なルール詳細の事ならともかく、この大枠の話の何がそんなに原則外れで難しいと思ってるのか正直さっぱりわからない
0042デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 13:24:55.21ID:Ma0XsUW1M
>>37
[補足4]
fという名前だが仮引数の型が異なる持つ関数f()が複数ある場合は、
f(a);
と書いた場合、aの部分が完全に意味解釈されて、aの型が完全に決まってから、
どのf()が呼び出されるかを選択。
選択されたf()の仮引数の型Tと実引数aの型を比較して、異なっていれば、
aの型をTに変換する変換関数を呼び出し、変換後の値を関数f()の引数として
関数f()を呼び出す。

ところが、初期化子の場合、
T v = b;
と書くと、bの型を軽く調査するが、完全には b が意味解釈される前にどの T のコンストラクタ
を呼び出すべきかの調査が始まる。その時点では、bの型は完全には決まってない。
0043デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 13:28:29.70ID:Ma0XsUW1M
>>41
>初期化子をコンストラクタのオーバーロード候補(静的に決まる)にそれぞれ適合させてみて、どれもダメならエラー、複数当てはまるなら優先度に従って1個に絞れたらそれを選択、曖昧ならエラー
Tのどのコンストラクタを使うかが決まるまでは、初期化子の中身の型が決まりません。
なので、総当り的にチェックすることが不可能だということになります。
(原因と結果が逆なので)。
なお、Tのどのコンストラクタを使うかを決める際に、初期化子のある程度の様子は
必要になりますのでややこしくなっています。
0045デフォルトの名無しさん (スプッッ Sd12-oy7h)
垢版 |
2022/11/10(木) 15:49:32.45ID:kY0Aveh/d
>>43
型が決まらないって何のこっちゃ
君の例だと"David Hyme"はconst char*だし123456はintだし、
{"David Hyme",123456}はEntry(に集成体初期化で暗黙変換可能)で、他の要素も全部そうだから初期化子全体はinitializer_list<Entry>(に暗黙変換可能)なのでvector(initializer_list<Entry>)が適合可能、って全部静的に決まる話だぞ(正確にはもっとややこしいけど)
どこに動的型が出てくると思った?
0047デフォルトの名無しさん (ササクッテロロ Sp79-uppo)
垢版 |
2022/11/10(木) 21:44:22.55ID:xu9+brpFp
プログラムは書いた通りにしか動かない

って奴だな
0052デフォルトの名無しさん (ササクッテロロ Sp79-uppo)
垢版 |
2022/11/10(木) 22:23:43.35ID:xu9+brpFp
頭が良い人なら、馬鹿にも分かる説明も難なくこなすんだがなぁ
自称してるだけの馬鹿なら意味不明な話を相手の理解力のせいにするんだよなぁ
0053デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 22:25:12.06ID:XJxScCwYM
>>45
例えば、class定義の中身Xが同じでも、class A {X} と class B {X} では別の型です。
その意味で、型が決まってないのです。
繰り返しますが、あなたはC言語の基礎が理解出来てないか、または、IQが
この質問に対して足りてない可能性があります。
0055デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/10(木) 22:29:41.43ID:XJxScCwYM
>>53
[補足]
{"aaa",1234}は、>>28のEntryとよく似た方では有りますが、コンパイラ内部では
Entryとは認識されません。仮に、
struct EntryB { const char *name, int number; };
とすれば、{"aaa",1234}は、中身の型としてはEntryBと全く同じと言えますが、
EntryBではないのです。
これが理解できないならば、C言語の基礎が理解出来てないので、質問の
意味が理解できないでしょう。
0059デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/11(金) 00:01:29.20ID:J8vKnsQy0
あー君が何を勘違いしてるのか分かってきた
「初期化子`{"aaa",1234}`の型」というものがあると勘違いしてるんだな
こいつは「const char*とintの要素が並んだ波括弧初期化子」であってこれ全体が型を持ってるわけじゃない
あくまで「Entryを初期化(暗黙変換)出来る初期化子」「EntryBを初期化出来る初期化子」でしかなくて、これ自体をEntryとかEntryBとかそのものだと思いこんでるのが君の根本的な間違いだ
(関数呼び出しfoo(1,2);の(1,2)だけ取り出してこの型は何だ?と聞いてるのと同じようなものでナンセンス)

初期化子の仕事はあくまで初期化なんだから、同じ文字列の初期化子でもその初期化対象の型(が許している初期化方法)によって意味は変わる
Entryのようにstringとintを持った構造体なら集成体初期化になるし、
(const char*, int)の引数を取るコンストラクタ(非explicit)の呼び出しにもなるし、
initializer_list<Foo>(Fooはconst char* とintの両方から暗黙変換できる型)にもなれる
なれるというか、初期化対象型のコンストラクタオーバーロードに対して一番適合するものを探し出す(無理ならエラーにする)のがコンパイラの仕事で、当然全部静的に決まるようになってる
こういう風に同じ波括弧にいろんな解釈方法を持たせることで初期化を柔軟に書けるようになってるわけだ(C++11で導入されたuniform initialization)


キチガイみたいだから優しく教えるのはこれで最後にする
すまんかったね
0060デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 00:16:31.96ID:NMTpQElqM
>>59
型を持ってるわけじゃないのは当然なのに、あなたが「動的型」というこっちが
言ってないことを勝手に妄想しだしたので、基礎から解説したまでです。
こっちの方が圧倒的に頭がいいので、食い違うのです。
0062デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 00:22:09.88ID:NMTpQElqM
>>59
このような場合にC++では型が静的に決まるのは当たり前。
あなたこそ、動的言語を前提にしているように思える。
そういうことではなくて、コンパイラが内部でどのような順序で「静的に」翻訳作業を
行なっているかを質問している。
コンパイラ内部では型を持って無くても、構文ツリーや色々な形でデータを
持っているが、仕様では、その順序までも決まってないとコンパイラで非互換性が
出てきてしまうし、何より、C++では演算子のオーバーロードなども出来る訳
だから、コンパイラの内部的な解釈の順序まで厳密に仕様化されてなければ、
一般プログラマも混乱が生じる。
その事を聞いている。
0063デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 00:26:17.38ID:NMTpQElqM
>>62
[補足]
JSなどの動的で初心者ならば、「大体」で理解していればそれで問題無い事が
多いだろうが、C++では、テンプレートもあればoperator+()演算子や型変換
演算子などをオーバーロードできるから、「大体」では駄目で、非常に細かな
コンパイルの順序や解釈の流れまでが言語の仕様書に厳密に書いてなければ
正しいアプリケーションコードを書くことが出来ないことがある。
「直感的に簡単に理解できるのに、何この馬鹿は聞いているんだ?」
などと思っているとすれば、大間違いだ。
0065デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 00:32:42.01ID:NMTpQElqM
>>63
[補足]
>>28で、phone_bookの初期化子について、「直感的に」理解できたら
それで十分、などと考えている人は、馬鹿なので質問には答えないで下さい。
C++コンパイラは、そのように大体で動作しているのではなく、パターン
に当てはめて順序を追ってコンパイルを進めていきますが、その順序や
解釈の仕方がC++03の時代とはかなり違っているように思えたから
質問したのです。
例えば、>>28は単なる例であって、これの応用として非常に複雑なコードを
書いた場合でも、コンパイラはなんたかの単純な法則に従って厳密に翻訳していきます。
その正確な規則が分からないから聞いているのです。
0067デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 00:40:51.17ID:NMTpQElqM
>>59
>Entryのようにstringとintを持った構造体なら集成体初期化になるし、
今回の例では、vector<Entry>型の初期化ですので、そんな単純ではありません。
vector<T,A>テンプレートのコンストラクタが呼び出されるはずです。
しかも、コンストラクタの種類が沢山ありますから、それを選ばなくてはなりません。
Entry a = {"xxx",1234};
ならば集成体初期化ですから、コンストラクタを選ぶ工程は無いはずですから、
比較的単純です。
ところが、今回の場合は、コンストラクタの選択から始まります。
しかし、初期化子自体の型が中途半端な状態でコンストラクタを選ぶ必要が
ありそうなので質問しているのです。

C++03で、x+y書いた場合、xとyの型が決まった後で、operator+(U,T)演算子を探します。
ところが今回の場合、初期化子の部分の型が中途半端な状態なので、コンストラクタを探す
ための手がかりが中途半端にしかないのです。
0068デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 00:45:48.11ID:NMTpQElqM
>>67
[補足]
CPerson person{"Suzuki", 25};
と書いた場合、CPersonのコンストラクタはすぐ探せます。
ところが、>>28 のように
vector<Entry> phone_book = {
 {"David Hyme",123456},
 {"Karl Popper",234567},
 {"Bertrand Arthur William Russell",2345678}
};
の場合、テンプレート vector<T,A> の中のコンストラクタを選ぼうとしても、
初期化子の{"David Hyme",123456}には、ある意味では「型が存在してない」ので
通常のように探すことは出来ないのです。
0069デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/11(金) 00:48:44.75ID:J8vKnsQy0
>>65
正確な規則が知りたいのに規格に当たることすら思いつかないのか自称天才のボンクラ様ってのは
9.4 Initializers [dcl.init](C++20公開ドラフトN4861、正規の規格がいいなら自分で買え)を見ればいいよ
誰でも読めば分かるように書いてある規格を天才様が理解できないなんてありえないから以降質問禁止な
0070デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 00:55:21.61ID:NMTpQElqM
>>68
[補足]
vectorは配列と似ていますが、コンパイラの内部的にはかなり違う扱いになっていて、
Entry a[3] = {
 {"David Hyme",123456},
 {"Karl Popper",234567},
 {"Bertrand Arthur William Russell",2345678}
};
と書いたならば、コンパイルの翻訳過程は全く異なってきます。
この場合はとても単純で、
T a[N] = {XXX};
の形式は、配列初期化として特別処理されています。
なので、コンストラクタを探す工程、というものが必要ありません。
そして、{"David Hyme",123456} の型を知る必要も無く、単純に、
Entryのメンバに代入していくような処理となります。
この場合の処理は、まず最初に配列型として処理が入り、次にEntryの構造体型
としての処理が入ります。
これが理解できない人は質問には答えないで下さい。混乱の元になります。
0072デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/11(金) 00:59:02.50ID:J8vKnsQy0
>>68
あまりにも馬鹿すぎて哀れだからもう1回だけ助け舟出してやる
いいか?vector<Entry>がどんなコンストラクタ持ってるか(どうオーバーロードされてるか)は決まってんだよ
vectorテンプレートを実体化した時点で静的に全部決まってんだよ
馬鹿なお前だって<vector>ヘッダを隅々まで読めば列挙くらい出来るのは分かるだろ
vector<Entry>のコンストラクタは例えばvector<Entry>()とかvector<Entry>(size_type)とかvector<Entry>(vector<Entry>&&)とかvector<Entry>(initilaizer_list<Entry>)とか色々あるわけだな(全部は挙げんぞ)
コンパイラ様はまずそれを列挙するわけだ。そして
・vector<Entry>()かな?→空じゃないからダメ
・vector<Entry>(size_type)かな?→{...}はsize_typeに変換できるかな?→ダメ
・vector<Entry>(vector<Entry>&&)かな?→{...}はvector<Entry>&&に変換できるかな?→ダメ
・vector<Entry>(initilaizer_list<Entry>)かな?→{...}はinitilaizer_list<Entry>に変換できるかな?→OK!
・...
ってひたすら一つずつ試すわけだ。で、vector<Entry>(initilaizer_list<Entry>)しか当てはまるものがないので、じゃあこれだとオーバーロードを解決するわけだ
コンパイラのやってることなんて基本的にこれだけだ、実に単純な話だ
こんな単純なこともわからずグチグチグチグチとお前は本当に無能だな
0073デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 01:02:30.49ID:NMTpQElqM
>>72
その探し方は、普通の関数のオーバーロード解決とは異なっていますね。
しかも、あなたの言っているほど単純じゃない。
実際は、優先順位があり、先に優先順位の低いものが見つかって、後から
優先順位が高いものが見つかっても、後の方が優先される。

あなたが馬鹿なのは、単純に考えすぎていることだ。
0074デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/11(金) 01:03:31.20ID:J8vKnsQy0
>>71
なんで答えが書かれた文書が誰でも読めるように公開されてるのに、わざわざ自分より劣った人間に答えを求めるの?
お前天才なんだろ?ここの誰よりも賢いんだろ?
消えな
0076デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 01:05:05.21ID:NMTpQElqM
>>73
[補足]
なお、関数のオーバーロード解決でも、「変換できるかどうか」とかそんな単純な
ものじゃないです。
例えば、T a{x} のように{}が書いてあれば、中味が1個しか書いてなくても、
initializer_list が優先される、などと決まってます。
0080デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 01:07:50.72ID:NMTpQElqM
>>77
あなたみたいなのが日本を衰退させている。
自分が頭がいいと思い込んでいるがかなり間違ってるし、レベルが低い。
そして、あなたの周りにはレベルの低い人しか回りに居ないから勘違いが
直らない。
0085デフォルトの名無しさん (オイコラミネオ MM91-wgF3)
垢版 |
2022/11/11(金) 01:11:25.32ID:NMTpQElqM
>>82
お前は理解できてないのに質問に答えようとしている。
いつもは質問のレベルが低いから答えられているんだろうが、今回は
お前の能力を超えている。
そしていつもの調子で質問者をレベルが低いと思い込んでいるから
馬鹿にした態度をとる。
0088デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/11(金) 01:16:18.16ID:J8vKnsQy0
もう終わりにするけど、俺の説明が間違ってるって言うならそれは規格と主要コンパイラの実装が間違ってるってことだから
ISOとベンダーに報告しときなよ

>>75
ごめんなさいみなさん久しぶりに面白いおもちゃだったのでつい
0090デフォルトの名無しさん (ワッチョイ d924-OvQ8)
垢版 |
2022/11/11(金) 05:29:55.03ID:wl59B58M0
std::array<T, N>って「N個の値xで埋める」コンストラクタありませんよね?
後でstd::fillするのが普通のやり方かもしれませんが、実際はstd::arrayのインスタンスができた時点でN個の何らかの初期値が入るんですよね?
この仕様に困ってます。
例えば、boost::multi_arrayは構築時にメモリの並び方 (Cライク or fortranライク) が決まって、後で変更する方法は提供されてないんですが、 std::array<boost::multiarray, N> を作ってしまうとメモリの並び方が勝手に決まってしまいます。
std::array の各要素のコンストラクタをこちらで呼ぶ方法があったら教えてください。
初期化リストで構築するやり方はNが大きいときは現実的でないので考えておりません。
0092デフォルトの名無しさん (ワッチョイ f57c-q4d/)
垢版 |
2022/11/11(金) 07:44:40.78ID:J8vKnsQy0
>>90
残念ながらarrayで初期化時にやるのは無理
arrayは組み込み配列と同じ初期化方法(集成体初期化)しか出来ないように意図的に設計されてて特別なコンストラクタを持たない
だからarray::fill()が用意されてるので普通はそれを使う
どうしてもその場で要素のコンストラクタを直接呼びたいなら一回構築してから要素ごとにデストラクタ→placement newを呼ぶしかない
最初のデフォルト構築も許せないならarray(と組み込み配列)を使うのは諦めよう
0102はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2b3e-BvCT)
垢版 |
2022/11/12(土) 14:25:39.92ID:5guAadWy0
>>90
要素のデフォルトコンストラクタは呼ばれるので要素のほうに適当なラッパーを被せるという方法はとれなくはない。
こういうラッパーならスタンダードレイアウトの要件は満たすのでバイト列レベルでも互換性は維持されるはず。

#include <array>
#include <iostream>

struct foo {
// このコンストラクタを呼んで欲しい
foo(int x){
std::cout << x << std::endl;
}
};

template <class T, auto N>
struct initializing_wrapper : public T {
initializing_wrapper(void) : T(N) {}
};

int main() {
std::array<initializing_wrapper<foo, 1> , 3> foo;
}
0105デフォルトの名無しさん (ワッチョイ c5c2-H0Ic)
垢版 |
2022/11/13(日) 04:06:31.61ID:L3LR+iGt0
ちょ、何これ? 聞いてないんだけど。。。

C:/msys64/mingw64/include/c++/12.2.0/bits/stl_pair.h:326:13: note: declared here
326 | pair& operator=(const pair&) = delete;

C:/msys64/mingw64/include/c++/12.2.0/bits/stl_pair.h:715:5: note: declared here
715 | swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
0106デフォルトの名無しさん (ワッチョイ 6597-6rMO)
垢版 |
2022/11/13(日) 07:39:53.36ID:alAGhxI40
>>103
eigen一回も使ったことないしググってもないけど、行列の先頭要素のメモリにアクセスする方法が提供されてないわけないので、それを使う
普通はdata()とかget()なるメンバ関数がある
0109はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2b3e-BvCT)
垢版 |
2022/11/13(日) 14:31:41.33ID:sejtbDAm0
>>105
本来使われるはずの定義はこっち。
https://github.com/gcc-mirror/gcc/blob/e24b430f1ea60205162fd9b327ac6a4dfc57f37c/libstdc%2B%2B-v3/include/bits/stl_pair.h#L371-L379

必要な性質 (要素の型が copy_assignable) が満たされていないときに最も優先度が低いやつが選択された上でそれが delete されているということになるんだと思う。
https://github.com/gcc-mirror/gcc/blob/e24b430f1ea60205162fd9b327ac6a4dfc57f37c/libstdc%2B%2B-v3/include/bits/stl_pair.h#L368
0111はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2b3e-BvCT)
垢版 |
2022/11/13(日) 18:18:04.90ID:sejtbDAm0
どうせ使えないなら使おうとしたときに static_assert で問題点を出すようにしたらいいのにと思ったがよく考えるとそれは駄目なんだな。
適用できるものがないということを SFINAE のトリックに使うことがあるかもしれない。
(static_assert が展開されると他の候補があっても問答無用で終わりになってしまう。)
0113デフォルトの名無しさん (アウアウウー Saa9-FFna)
垢版 |
2022/11/14(月) 12:10:20.06ID:EWF0SvAna
>>94-95
天才とパンピーで理解レベルのバックグラウンド知識に差があるからだろ
その差を埋める説明を一瞬で出来る人はそれなりの才能があるとは思うが
天才同士ならそんな説明いちいちしなくても判り合えるんだ
0115デフォルトの名無しさん (US 0Ha3-XgLS)
垢版 |
2022/11/14(月) 22:27:38.95ID:sRgsAS70H
自分が天才だ!とわざわざ自称しなくても、天才らしい雰囲気をかもし出せるレスはないものでしょうかね…
自称天才はもういいし
0117デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/15(火) 12:36:06.45ID:+zOZoQ9YM
プログラミング言語 C++ [第四版], 日本語訳 の p.689 に、
template<typename T>
class Xref {
 ・・・
};
template<typename TT, typename A>
unique_ptr<TT> make_unique(int i, A&& a)
{
 return unique_ptr<TT>{new TT{i,forward<A>(a)}};
}
auto p1 = make_unique<Xref<String>>(7,"Here");
「ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&)
が呼び出される。」
とありますが、実引数の文字列リテラル "Here" が、make_unique()の
仮引数 A&& に渡そうとしたら、A = string と「演繹」されているようですが、
const char* 型が string に至るまでの仕組みか分かりません。
どなたが分かる人居ませんか?

実際の STL の sting は basic_string<U> テンプレートの U=charの
場合だと思われますが、意味を概念的に言えば、
class string {
public
// 変換コンストラクタ :
string(const char *) {・・・}
};
という「変換コンストラクタ」があるでしょうから、それが使われている
ことは推定は出来ます。
しかし、上記のテンプレートで T を演繹する際に、このような変換コンストラクタ
が呼び出されるメカニズムが分かりません(仕様書のどこに書いてあるのかが
分からない。)。
0118デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/15(火) 12:51:05.19ID:+zOZoQ9YM
>>117
もっと詳しく書くと、直前から次のように書かれています:
# Xref<String>はXref<string>の写し間違いでした。
string x {"There and back again"};
template <typename T>
T&& std::forward(typename remove_reference<T>::type& t) noexcept;
template <typename T>
T&& std::forward(typename remove_reference<T>::type&& t) noexcept;
ここで望まれるのは、不純なコピーを一切作ることなく、
make_unique<T>(arg)がargからTを構築することである。
その実現には左辺値と右辺値の区別を管理することが重要だ。
次の例を考えてみよう:
template<typename TT, typename A>
unique_ptr<TT> make_unique(int i, A&& a) // make_sharedのちょっとした変種
{
 return unique_ptr<TT>{new TT{i,forward<A>(a)}};
}
auto p1 = make_unique<Xref<string>>(7,"Here");
ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&)
が呼び出される。
そして、"Here"を格納しているstringのムーブを行なうために、
Xref(int,string&&)が呼び出されることになる。
# 個人の感想: これは、A=stringと考えられます。
もっと興味深い(しかも分かりにくい)のが、次のものだ:
auto p2 = make_unique<Xref<string>>(9,x);
ここで、xが左辺値なので、左辺値を引数にforward(string&)が呼び出される。
forward()のTは、string& と導出される。そのため、返却値は string & &&となる。
もちろんそれは string & を意味する(§7.7.3)。その結果、左辺のxに対して、
Xref(int,string&)が呼び出されて、xがコピーされる。
# 個人の感想: これは、A=string&と考えられます。
0121デフォルトの名無しさん (スップ Sd43-m1Df)
垢版 |
2022/11/15(火) 12:57:17.27ID:slZuGS0Ed
make_uniqueの実体化の所でTT=Xref<String>、T=Stringって明示的に指定してるじゃん
「演繹」なんかするまでもないから規格に書いてるはずもない
天才のくせにそんな事も分からないの?
0122デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/15(火) 13:00:23.02ID:+zOZoQ9YM
>>119
[ヒント]
前頁p.688の下段:
「左辺値と右辺値は、テンプレート引数の導出では区別される。
X型の左辺値はX&として導出されて、右辺値はXとして導出される。
これは、非テンプレート引数の右辺値参照への値のバインド
(§12.2.1)とは異なる。
しかし、引数転送(§35.5.1)においては、極めて有用だ。
Xrefを空き領域上に置いて、そのポインタをunique_ptrとして
返すファクトリ関数を記述する場合を考えてみよう:

の直後、ページが変わってページの最初に>>118の std::forward テンプレート
の定義が書いて有ります。
0125デフォルトの名無しさん (ワッチョイ 23a5-gPc0)
垢版 |
2022/11/15(火) 14:16:43.16ID:D78/LkiC0
new TT{i, forward<A>(a)}
既出だが、こう書いてあってもXrefのメンバの型がどうなるか分からんわけでしょ

先日の質問と合わせて、型パズルをスラスラ解けるような資質がない
資質がないんでXrefの『関係ない』としたところを「・・・」で埋めてる
0127デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/15(火) 16:18:06.60ID:Q+AZCxhHM
>>126
命題『A が const char (&)[5] に推論される』・・・☆
とし、背理法で考えます。
☆が正しいと仮定すると、
forward<A>(a)は、forward<const char (&)[5]>(a)となりますが、すると、
template <typename T>
T&& std::forward(typename remove_reference<T>::type& t) noexcept;
template <typename T>
T&& std::forward(typename remove_reference<T>::type&& t) noexcept;
に対して、forward<const char (&)[5]>(a)
が呼び出されることになります。
しかし、
>auto p1 = make_unique<Xref<string>>(7,"Here");
>ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&)
>が呼び出される。
とBJ stroustrup氏が書いています。
ならば、T=const char (&)[5]の時に、
typename remove_reference<T>::type
がstringにならなければなりません。つまり、
typename remove_reference<const char (&)[5]>::type
がstringになってないと矛盾する事になります。
もし、矛盾するならば、背理法により、☆は否定されることになります。
(矛盾しそうです。)
0131はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2b3e-BvCT)
垢版 |
2022/11/15(火) 18:04:53.44ID:5Bng48RE0
>>127
> ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&)
> が呼び出される。

文字列リテラルは左辺値。 右辺値だと書いてあるのならそれが間違っている。
配列がポインタに (暗黙的でも明示的でも) キャストされる文脈では
そのポインタは xvalue (おおよそ右辺値のような扱いになる分類) になるが、
今回は変換が入らずに参照で受けているのでそうはならない。

/// この場合は rvalue 扱い
#include <cstdio>
void foo(const char *&x) { std::printf("lvalue"); }
void foo(const char *&&x) { std::printf("rvalue"); }
int main(void) { foo("abc"); }

/// この場合は lvalue 扱い
#include <cstdio>
template <class T> void foo(const T &x) { std::printf("lvalue"); }
template <class T> void foo(const T &&x) { std::printf("rvalue"); }
int main(void) { foo("abc"); }
0132デフォルトの名無しさん (ワッチョイ d55f-cfOC)
垢版 |
2022/11/15(火) 18:53:35.18ID:mUSyU2rD0
文字列リテラルが左辺値ってなんで?
0136はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2b3e-BvCT)
垢版 |
2022/11/15(火) 23:54:26.84ID:5Bng48RE0
配列 (文字列を含む) と関数は値として扱えない、勝手にポインタに型変換するという
C から引き継いだ変則的なルールに辻褄を合わせているので全体的に変則的で
分かりにくいんだよ……。
0137デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 00:19:44.88ID:g3O9ReAZM
>>131
>auto p1 = make_unique<Xref<string>>(7,"Here");
>ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&)
>が呼び出される。
と書かれています。
なので、"Here"がなんらかのメカニズムでstd::stringに変換されていると
解釈しました。
実験すれば白黒はっきりさせることが出来るかも知れません。
0140デフォルトの名無しさん (ワッチョイ cd7c-sQ55)
垢版 |
2022/11/16(水) 00:32:07.57ID:Nbbm6FAB0
禿本手元にないから確認はできないけど、「"Here"が右辺値」なんて基本的な間違い書くとは思えないんだけど
侵害くんの読み間違いか書き間違いか、本当に書いてあるなら翻訳ミスじゃないの
0141デフォルトの名無しさん (ワッチョイ cd7c-sQ55)
垢版 |
2022/11/16(水) 00:32:57.76ID:Nbbm6FAB0
>>139
"Here"の配列→(配列とポインタの糞ルール)→const char*→(stringの変換コンストラクタ)→string
と変換された結果のstring一時オブジェクトが右辺値だってクドクド書いてない?ちゃんと読んだ?
0142デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 00:38:01.28ID:g3O9ReAZM
原書(英語版)はこうなってます:
23.5.2.1. Reference Deduction
...

template<typename T>
class Xref {
public:
   Xref(int i, T* p)    // store a pointer: Xref is the owner
      :index{i}, elem{p}, owner{true}
   {}
Xref(int i, T& r)    // store a pointer to r, owned by someone else
      :index{i}, elem{&r}, owner{false}
   {}
Xref(int i, T&& r)   // move r into Xref, Xref is the owner
      :index{i}, elem{new T{move(r)}}, owner{true}
   {}
~Xref()
   {
      if(owned) delete elem;
   }
   //...
private:
   int index;
   T* elem;
   bool owned;
};
...
0143デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 00:38:41.12ID:g3O9ReAZM
>>142
template<typename T>
  T&& std::forward(typename remove_reference<T>::type& t) noexcept; //§35.5.1
template<typename T>
  T&& std::forward(typename remove_reference<T>::type&& t) noexcept;
template<typename TT, typename A>
unique_ptr<TT> make_unique(int i, A&& a)   // simple variant of make_shared (§34.3.2)
{
  return unique_ptr<TT>{new TT{i,forward<A>(a)}};
}

We want make_unique<T>(arg) to construct a T from an arg without making any spurious copies. To do that, it is essential that the lvalue/rvalue distinction is maintained. Consider: auto p1 = make_unique<Xref<string>>(7,"Here");

"Here" is an rvalue, so forward(string&&) is called, passing along an rvalue, so that Xref(int,string&&) is called to move from the string holding "Here". The more interesting (subtle) case is: auto p2 = make_unique<Xref<string>>(9,x); Here, x is an lvalue, so forward(string&) is called, passing along an lvalue: forward()’s T is deduced to string& so that the return value becomes string& &&, which means string& (§7.7.3). Thus, Xref(int,string&) is called for the lvalue x, so that x is copied.

Stroustrup, Bjarne. The C++ Programming Language (p.689). Pearson Education. Kindle 版.
0144デフォルトの名無しさん (ワッチョイ d55f-NNfd)
垢版 |
2022/11/16(水) 00:40:39.32ID:85X5ndMu0
C++ど素人なんですが、この画像のようなファイル群がある時に、Visual Studioでexe化するにはどうしたら良いですか?

まず、ファイルはsln形式などになってないですが、そういったものはつくる必要はなく、ExpressionApp.cppだけ開いてビルドボタンを押したりすれば良い感じなのでしょうか?
0148デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 00:42:22.40ID:g3O9ReAZM
>>140
"Here" is an rvalue, so forward(string&&) is called, passing along an rvalue, so that Xref(int,string&&) is called to move from the string holding "Here".

>>141
テンプレート関数なので、Aという方引数が決定されるメカニズムが重要となります。
Aがstringに決定されたならば、文字列リテラルからstringへの変換法則はおなじみの
ものとなります。
それよりも、まず、どうしてAがstringに決定されたのかの「仕組み」が分かりません。
0150デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 00:50:02.83ID:g3O9ReAZM
>>143
142と143の間に、次の記述が挟まっています。
So:
string x {"There and back again"};
Xref<string> r1 {7,"Here"}; // r1 owns a copy of string{"Here"}
Xref<string> r2 {9,x}; // r2 just refers to x
Xref<string> r3 {3,new string{"There"}}; // r3 owns the string{"There"}

Here, r1 picks Xref(int,string&&) because x is an rvalue.
Similarly, r2 picks Xref(int,string&) because x is an lvalue.
Lvalues and rvalues are distinguished by template argument deduction:
an lvalue of type X is deduced as an X& and an rvalue as X.
This differs from the binding of values to non-template argument rvalue references (§12.2.1)
but is especially useful for argument forwarding (§35.5.1).
Consider writing a factory function that make Xrefs on the free store and returns
unique_ptrs to them:
0151デフォルトの名無しさん (ワッチョイ d55f-NNfd)
垢版 |
2022/11/16(水) 00:50:03.82ID:85X5ndMu0
>>147
ありがとうございます
やってみます
0152はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2b3e-BvCT)
垢版 |
2022/11/16(水) 00:51:20.49ID:eOApcCVI0
>>137
文字列リテラルが lvalue なのはややこしい解釈の余地はなく直接的に明記されている。
https://timsong-cpp.github.io/cppwp/n3337/expr.prim.general#1

少なくとも

> "Here"は右辺値なので

というのは確実に誤った記述だよ。
最初の段階で誤っているのだからそこから後の理屈の立て方に筋が通るはずがない。

>>148

A は string に決定されない。
そういう仕組みは無いのでそれを前提として考えるな。
0153デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 01:10:00.99ID:g3O9ReAZM
>>152
>A は string に決定されない。
>そういう仕組みは無いのでそれを前提として考えるな。
なるほど。しかし、だとすれば、
「Consider: auto p1 = make_unique<Xref<string>>(7,"Here");
 "Here" is an rvalue, so forward(string&&) is called, passing along an rvalue,
 so that Xref(int,string&&) is called to move from the string holding "Here".」
の部分はどう説明できますか?
0154デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 01:14:18.30ID:g3O9ReAZM
>>153
今思ったんですが、もしかしたら、
>Consider: auto p1 = make_unique<Xref<string>>(7,"Here");
の部分が、
Consider: auto p1 = make_unique<Xref<string>>(7,string{"Here"});
の書き間違いだったのかもしれませんね。

なお、直接関係有りませんが、>>150
>Xref<string> r1 {7,"Here"}; // r1 owns a copy of string{"Here"}
>Here, r1 picks Xref(int,string&&) because x is an rvalue.
は、確認しましたが、kindle版は確かに正確にこう書かれていますが、
このr1の定義部分に「x」は存在しておらず、代わりに"Here"が存在していますので
そこも書き間違いかも知れません。
0155デフォルトの名無しさん (オイコラミネオ MM71-ZKGJ)
垢版 |
2022/11/16(水) 01:26:05.39ID:g3O9ReAZM
もしくわ、
>auto p1 = make_unique<Xref<string>>(7,"Here");
は、
auto p1 = make_unique<Xref<string>,string>(7,"Here");
と書きたかったのでしょうか。つまり、もし、
auto p1 = make_unique<Xref<string>>(7,string{"Here"});
または、
auto p1 = make_unique<Xref<string>,string>(7,"Here");
と書いてあったならば、辻褄が合いそうです。
0156デフォルトの名無しさん (ワッチョイ a501-WFXv)
垢版 |
2022/11/16(水) 05:12:39.73ID:c3tWnPnh0
文字を反転させる関数を作っているのですがうまく行きません
voidの部分がおかしいと思うんですが正直手詰まりです
誰か解決策はありますでしょうか
実行するとrevarce関数が飛ばされて終了してしまいます

void revarse(char* p, char* r);
int main(void)
{
char str1[64];
char str2[64] = {};

printf("文字列を入力\n>>");
scanf("%s", str1);

revarse(str1, str2);

printf("%s", str2);

rewind(stdin);
getchar();
return 0;
}
//反転させる関数
void revarse(char* p, char* r)
{
int len = strlen(p);

for (int i = 0; i <= len / 2; i++)
{
*(r + i) = *(p + (len - i));
}
}
0158デフォルトの名無しさん (ワッチョイ 23ad-Y93w)
垢版 |
2022/11/16(水) 05:33:02.42ID:5+x4ry0S0
>>156
文字列pが "12345" だとして考えてみ?
len=5 だろ?

*(p + (len - i));

これって i=0 の時 *(p + (5 - 0)) => *(p + 5) ってことになる

ゼロベースだからインデックス5にはNULL文字'\0'が入っている
それを*r にコピーしている
つまりコピーされるのは常に長さ0の文字列
そりゃ出力したってなにも表示されないさ

あとlen / 2はおかしいだろ
練習するならマルチバイトはまず置いておいてシングルバイト文字のみ扱え
0167デフォルトの名無しさん (アウアウウー Saa9-FFna)
垢版 |
2022/11/16(水) 17:43:24.39ID:z+sJwdsYa
>>144
>>147 が正解だが
Readme.txt も読んだか?
0169デフォルトの名無しさん (アウアウウー Saa9-FFna)
垢版 |
2022/11/16(水) 17:47:22.63ID:z+sJwdsYa
>>161-162
Nim
0170デフォルトの名無しさん (ワッチョイ 5f01-KP+k)
垢版 |
2022/11/19(土) 11:03:08.07ID:GrOHAxDN0
>>161
vectorの取りうるサイズがある程度決まってるのなら
予めdoubleの数が異なるtupleを用意しておくという手はある

#include <iostream>
#include <any>
#include <vector>
#include <tuple>
using namespace std;
using Vector = vector <double>;
using Int_Double_1 = tuple <int, double>;
using Int_Double_2 = tuple <int, double, double>;

any make_tuple_from_int_vector (int p0, const Vector &p1)
{
if (p1.size () == 1)
return make_tuple (p0, p1 [0]);
else if (p1.size () == 2)
return make_tuple (p0, p1 [0], p1 [1]);
else
return any ();
}

int main ()
{
Vector v1 (1, 10);
Vector v2 (2, 100);
auto v3 (any_cast <Int_Double_1> (make_tuple_from_int_vector (1000, v1)));
auto v4 (any_cast <Int_Double_2> (make_tuple_from_int_vector (10000, v2)));
return 0;
}
0171デフォルトの名無しさん (アウアウウー Sa3b-kfYZ)
垢版 |
2022/11/19(土) 16:17:21.48ID:F8GIHVyHa
本当の目的を聴きたい
0172デフォルトの名無しさん (ワッチョイ cf5f-pHhH)
垢版 |
2022/11/19(土) 19:46:58.80ID:IQ1PkgMa0
true &&false計算するのと1&&0計算するのはどっちが早いとかある?
0173デフォルトの名無しさん (ワッチョイ 5701-kfYZ)
垢版 |
2022/11/19(土) 19:50:29.13ID:o7Lf802R0
はちみつもたまには役に立つな。
褒めてつかわす。
下がって良いぞ。
0175はちみつ餃子 ◆8X2XSCHEME (ワッチョイ b63e-stRS)
垢版 |
2022/11/20(日) 00:27:52.78ID:RgPem6BD0
>>172
オペランドがリテラルならコンパイル時に畳み込まれるので同じ。
そうではなく型による差について問うているのなら
少なくとも現代的な処理系・実行環境だとまず差は出ないよ。
うまいこと最適化されてそんな差はどうでもよくなる。

言語仕様通りの素朴な解釈だと両オペランドを bool に型変換するという工程が入るので
int の && のほうが余計に処理をすることにはなるが……。

ちなみに C と C++ では規則が違うので詳細を調べるなら混同しないように注意。
(文言は違うけど結果的な挙動はほぼ差はないんだけど。)
0177デフォルトの名無しさん (オイコラミネオ MM67-yS4u)
垢版 |
2022/11/20(日) 13:29:22.75ID:9/YCbfcZM
>>176
[補足]
最適化には高レベルから低レベルまでさまざまな層で行なわれる。
高レベルで複雑な多くのマシン語が生成されても、後段の低レベルで集成されて短い
コードになる。
&& や || は、シーケンスポイントがあり A && B は A が偽ならば B を評価しないし、
A || B は、A が真なら B を評価しないので、マシン語レベルで条件 jump 命令が
生成されることが有るが、&& や || は、「高レベル」でも最適化する方法が
知られているので、このような場合、条件 jump 命令が生成されない。
また、仮に高レベルでは条件 jump 命令が生成されてしまった場合でも、
低レベルで最適化する際に、必ず真になったり必ず偽になるような条件 jump は、
無条件jumpになったり、削除されたりする。
そして、直後の命令への無条件 jump は、削除される。
二段階の無条件 jump は一段階の jump に修正される。
このような最適化を何度も何度も繰り返すので、結果的に同じことをするコードは、
同じコードになることが多い。
0178デフォルトの名無しさん (オイコラミネオ MM67-yS4u)
垢版 |
2022/11/20(日) 13:42:45.47ID:9/YCbfcZM
>>177
誤:最適化には高レベルから低レベルまでさまざまな層で行なわれる。
正:最適化は高レベルから低レベルまでさまざまな層で行なわれる。

誤:高レベルで複雑な多くのマシン語が生成されても、後段の低レベルで集成されて短い
正:高レベルで複雑な多くのマシン語が生成されても、後段の低レベルで修正されて短い
0179デフォルトの名無しさん (スプッッ Sd22-FDdn)
垢版 |
2022/11/22(火) 08:37:00.41ID:JLBL5Nrvd
windowsでstd::create_symlinkを使おうとすると
特権がいるって言われるけど、何でそんな決まりになってんの?
mklinkコマンドも特権モードじゃないとシンボリックリンク作れないし
それのどこがそんなに危険な操作なのか理解に苦しむ
0183デフォルトの名無しさん (ワッチョイ e201-IwB9)
垢版 |
2022/11/22(火) 10:21:25.02ID:5norvibI0
ディレクトリの権限関係なくWindows のシンボリックリンクの作成自体に管理者権限が必要、理由は知らん
ディレクトリにリンク張るならジャンクション(こっちは管理者権限不要)使えってことかも
ジャンクションの作成はコマンドからならmklink /jで行けるけどコードからやるのはちょっと面倒みたい
https://stackoverflow.com/questions/29291059/issue-creating-windows-ntfs-directory-junction-in-c-c
0185デフォルトの名無しさん (ワッチョイ 06cf-zHbW)
垢版 |
2022/11/22(火) 16:27:39.36ID:tXIkHCtk0
>ユーザー権利を持つユーザーは、誤って、または悪意を持ってシステムをシンボリック リンク攻撃に公開する可能性があります。
>シンボリック リンク攻撃は、ファイルのアクセス許可の変更、データの破損、データの破棄、または DoS 攻撃として使用できます。
というのが、Microsoft の公式見解
0189デフォルトの名無しさん (ワッチョイ e201-IwB9)
垢版 |
2022/11/22(火) 17:02:07.48ID:5norvibI0
>>188
リンク先には攻撃方法は書いてないな

シンボリックリンク攻撃 でググるとこれが出てきた
特にWindows特有というわけじゃなさそう、て言うかWindowsは/tmpみたいな誰もが共通的に使うディレクトリはないからより攻撃は難しそうだが
https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c802.html
0190デフォルトの名無しさん (ワッチョイ cf5f-HmgA)
垢版 |
2022/11/22(火) 19:09:40.02ID:zDRYE0v60
他の人の書いたコードを読み解いています。

下の例では、キーが押されたら何かを切り替えてるのはわかるのですが、ここで使われている
・0xFの意味
・(1 << 0)などの右シフト?
がどういう使われ方をしてるのかが分からないので知りたいです。

16進数で掛け算して値を使っているのでしょうか?
単純な1,2,3,4などの数値で切り替えていないのも意図がよく分からないのでずが深い意味はありそうでしょうか?

// VIEW_MESH | VIEW_IMAGE | VIEW_PLOT | VIEW_LM
int _viewMode = 0xF;

enum
{
VIEW_MESH = (1 << 0),
VIEW_IMAGE = (1 << 1),
VIEW_PLOT = (1 << 2),
VIEW_LM = (1 << 3)
};

switch (key)
{
case 'i': _viewMode ^= VIEW_IMAGE; break;
case 'l': _viewMode ^= VIEW_LM; break;
case 'm': _viewMode ^= VIEW_MESH; break;
}
0191デフォルトの名無しさん (ワッチョイ e2ad-szhu)
垢版 |
2022/11/22(火) 19:21:19.72ID:3Sn7h5kH0
>>190
>・0xFの意味
16進数、10進数の15、2進数の1111

> ・(1 << 0)などの右シフト?
左シフト、1 << 0に関して言えば0ビットシフトなのでつまりシフトしない、二進数で0001、10進数で1
(1 << 1)は1ビット左にシフトなので二進数で0010、10進数で2
(1 << 2)は2ビット左にシフトなので二進数で0100、10進数で4
(1 << 3)は3ビット左にシフトなので二進数で1000、10進数で8
0192デフォルトの名無しさん (ワッチョイ e2ad-szhu)
垢版 |
2022/11/22(火) 19:40:28.84ID:3Sn7h5kH0
>>190
^= は複合代入演算子

_viewMode ^= VIEW_IMAGE は _viewMode = _viewMode ^ VIEW_IMAGE と同じ

^ は排他的論理和(ビットXOR)、二進数で 1001 ^ 1100 は 0110 になる、要はビットが同じなら偽、異なっていれば真という演算

>case 'i': _viewMode ^= VIEW_IMAGE; break;
_viewModeには1111が代入されている、VIEW_IMAGEは0010
1111 ^ 0010 は 1101 になる
その演算結果1101を_viewModeに代入する

一連のコードはビットをフラグとして扱っていて、初期値として全フラグを立たせ、keyに対して特定のフラグをへし折っている
0193デフォルトの名無しさん (ワッチョイ cf5f-HmgA)
垢版 |
2022/11/22(火) 20:24:07.39ID:zDRYE0v60
>>191
>>192
ありがとうございます
なるほど!フラグをへし折っているのですね納得です
0195デフォルトの名無しさん (ワッチョイ 5f01-KP+k)
垢版 |
2022/11/22(火) 22:14:00.95ID:+RKYLIKe0
始めたばっかりなんでしょ
ビットをフラグとして使うとか最初は面食らったな
0196デフォルトの名無しさん (ササクッテロリ Spdf-k7YZ)
垢版 |
2022/11/22(火) 22:48:40.37ID:s23xOfAqp
ファミコンでもあるまいし、いまどき1ビットに意味をもたせなんて、通信制御くらいしか思い付かないなぁ
0198デフォルトの名無しさん (ササクッテロリ Spdf-k7YZ)
垢版 |
2022/11/22(火) 23:04:06.68ID:s23xOfAqp
恋愛ゲームのフラグと同意語だよな
0199デフォルトの名無しさん (ワッチョイ 5f01-KP+k)
垢版 |
2022/11/22(火) 23:10:53.75ID:+RKYLIKe0
flagでしょ
大元は手旗信号
0201デフォルトの名無しさん (ササクッテロリ Spdf-k7YZ)
垢版 |
2022/11/22(火) 23:49:48.37ID:s23xOfAqp
>>200
そうか?普通#defineされてる名前を使うからあんま意識しないよ?
0211デフォルトの名無しさん (アウアウウー Sa3b-kfYZ)
垢版 |
2022/11/23(水) 12:34:44.63ID:DxhXFxCJa
istringstreamとかifstreamとかistreamとか
入力系からreadした場合実際に読めたバイト数は
.gcount()で取得出来ますが
ostringstreamとかofstreamとかostreamとか
出力系にwriteした場合実際に描き込めたバイト数はどうすれば取得出来ますか?
.pcount()とかは無いようです
0213デフォルトの名無しさん (アウアウウー Sa3b-kfYZ)
垢版 |
2022/11/23(水) 12:46:45.47ID:DxhXFxCJa
Nを指定して成功していたら必ずNは判りますが
未定義: 失敗したとき0かどうかは判らない
定義済(0): 0からNの間の値になる可能性は無い
の未定義にあたるということですかね
途中までならその途中までの数字が知りたいと思うのは不自然?
ありがとうございます
0215デフォルトの名無しさん (ワッチョイ fb7c-IsEx)
垢版 |
2022/11/23(水) 13:59:19.61ID:fdWr7Y/z0
書き込みエラーなんてプログラムからは何が起きてるかわかんないんだよ
最悪壊れかけのディスクにちょうどトドメ刺して何もかも吹っ飛んだのかもしれない
エラーが起きた時点でプログラム側で保証できることなんてほとんどないし、たまたま途中の何文字まで書けたかなんて大抵は無意味な情報

逆に読み込みで何文字読んだって情報は、プログラム側で管理してるメモリの話だからプログラムからも分かるし必要でもある
0217デフォルトの名無しさん (ワッチョイ 4228-17Q5)
垢版 |
2022/11/23(水) 23:37:54.49ID:t8T/jR0m0
質問なのですがenum class初心者なのですが
enum classはint以外の整数型としても定義できるそうなので
整数型への自動変換ぐらいしてくれるのかと思いきや、
 enum Foo { A, B, C, D, N };
 int arr[Foo::N];
 arr[Foo::A] = 1;
 arr[Foo::B] = 999;
みたいに配列の添え字に使うケースで
 error C2677: 二項演算子 '[': 型 'Foo' を扱うグローバルな演算子が見つかりません (または変換できません) (新しい動作; ヘルプを参照)。
というコンパイルエラーになります……orz
Visual Studio 2019なのですがおれ環?
0221デフォルトの名無しさん (ワッチョイ 5f01-KP+k)
垢版 |
2022/11/24(木) 01:18:48.76ID:4/0XLjMc0
スコープを限定したいときは以下のように俺は書いてるな

namespace Foo
{
enum { A, B, C, D, N };
}

int main ()
{
struct Bar
{
enum { A, B, C, D, N };
};
int arr0[Foo::N];
arr0[Foo::A] = 1;
int arr1[Bar::N];
arr1[Bar::A] = 1;
return 0;
}
0223はちみつ餃子 ◆8X2XSCHEME (ワッチョイ b63e-stRS)
垢版 |
2022/11/24(木) 02:01:14.76ID:7DmT43os0
>>217
enum class といいつつ enum で宣言しているところをみるに、
ひょっとして enum と enum class が別物であることを知らずに混乱しているのでは?
ちなみに enum class も class というキーワードを使いはするが分類上はクラスではないのも混乱するかもな。

> enum classはint以外の整数型としても

たぶん underlying type のことを言っているんだと思うが
指定しなかったときの underlying type は int ではなく
その列挙体における全ての列挙子を格納可能な処理系定義のなんらかの整数としか決まってない。
(格納可能である限りは int より大きくなることはないという制約はついているけど。)
0224デフォルトの名無しさん (ワッチョイ e201-IwB9)
垢版 |
2022/11/24(木) 06:18:15.26ID:0c/PVttN0
>>223
> 指定しなかったときの underlying type は int ではなく
> その列挙体における全ての列挙子を格納可能な処理系定義のなんらかの整数としか決まってない。
> (格納可能である限りは int より大きくなることはないという制約はついているけど。)
それunscoped enumeration typeの方
enum class は無指定だと int になる
https://cpprefjp.github.io/lang/cpp11/scoped_enum.html
0226デフォルトの名無しさん (アウアウウー Sa3b-eHBA)
垢版 |
2022/11/24(木) 08:35:12.79ID:0WkgaUasa
>>225
おれ環ではなくて仕様
0229デフォルトの名無しさん (スフッ Sd02-XhSM)
垢版 |
2022/11/24(木) 09:20:49.08ID:qRYWlPaYd
enumはいらないこ
0230はちみつ餃子 ◆8X2XSCHEME (ワッチョイ b63e-stRS)
垢版 |
2022/11/24(木) 11:00:48.22ID:7DmT43os0
歴史的経緯というやつだなぁ。
C では列挙子の型が int なんだよ。 列挙型は定義ごとに独立した型になるのに列挙子は整数そのものとして扱われる。
C++ では列挙子の型は列挙型に変更しつつも型変換がゆるゆるだから結果的に C とほぼ同じ挙動になって互換性が維持された。

あまりよくはないが C との連携は C++ の強みだから仕方がない。
でもさすがに扱いにくいから新しく enum class が作られたという経緯なので最初から使い分けを意図して二種類作られたわけではない。
enum の改良として enum class が出来たので一貫性がなく全く別物として成立している。
0235デフォルトの名無しさん (オイコラミネオ MM67-yS4u)
垢版 |
2022/11/24(木) 15:31:29.44ID:a85Uy2KJM
簡単そうに見えたけど、俺の中でなかなか理解できないのが explicit 指定。
明示的初期化、直接初期化、代入初期化(?)、暗黙の型変換の禁止、
などなど色々な概念があるし、頭の中で整理できてない。
「直接初期化」の定義が今一分かって無い。
0236はちみつ餃子 ◆8X2XSCHEME (ワッチョイ b63e-stRS)
垢版 |
2022/11/25(金) 09:44:10.24ID:9Oo+WeOy0
>>235
もちろん色々な概念と相互に関係はあるんだが explicit 指定に直接的に関連するルールは

・ 引数一個で呼び出せるコンストラクタ (デフォルト引数や可変長引数の場合も含む) は変換コンストラクタ (converting constructor) としても機能する
・ ただし explicit 指定がついている場合はそうならない

ってだけだな。
変換コンストラクタがいつ起動するのかはまた別の話として……。
0237デフォルトの名無しさん (スプッッ Sd22-TJ0J)
垢版 |
2022/11/25(金) 11:20:20.74ID:rtODN+wBd
C++03まではそうだったけど
11から複数引数にも波括弧からの変換を認めない機能が追加されてややこしくなってる

struct Hoge{
 /*explicit*/ Hoge(int,double,char*);
 …
};
Hoge foo(){
 return {42,3.14,”Hello”); // explicitだとダメ
}
Hoge h[] = { {1,1.0,””}, {2,2.0,””}}; //explicitだとダメ
0238デフォルトの名無しさん (アウアウウー Sa3b-kfYZ)
垢版 |
2022/11/25(金) 12:30:00.19ID:PV2ZG9bua
ハッシュを使って実現した連想配列をハッシュって呼ぶのは
携帯電話をケータイと呼ぶような類のこと
0240デフォルトの名無しさん (アウアウウー Sa3b-kfYZ)
垢版 |
2022/11/25(金) 12:47:02.94ID:PV2ZG9bua
>>237
こういうこと?
#include <iostream>
using namespace std;

struct Hoge{
int a;
double b;
char *c;
explicit Hoge(int _a, double _b, char *_c) : a(_a), b(_b), c(_c) {}
};

Hoge foo(){
return Hoge{42, 3.14, "Hello"};
}

Hoge h[] = {Hoge{1, 1.0, ""}, Hoge{2, 2.0, ""}};

int main() {
return 0;
}
0243デフォルトの名無しさん (オイコラミネオ MM67-yS4u)
垢版 |
2022/11/25(金) 14:21:14.78ID:TzWxad5dM
今まで本を読んでも、「直接初期化」「コピー初期化」
の厳密定義が分からなかったけど、英語版の en.cppreference.com
をそれぞれ
「direct initialization」「copy initialization」
で検索すると「全てのパターン(?)」の一覧が出てくるみたいだ。
0248デフォルトの名無しさん (ササクッテロリ Spdf-k7YZ)
垢版 |
2022/11/25(金) 20:32:13.35ID:kbwNStuYp
C++スレなんだがw
0251デフォルトの名無しさん (ワッチョイ cf5f-pHhH)
垢版 |
2022/11/25(金) 21:16:26.19ID:3wykxWfs0
ハッシュテーブルとかも知らなさそう
0252デフォルトの名無しさん (ワッチョイ a7c2-TaOI)
垢版 |
2022/11/25(金) 22:15:24.17ID:mXzsiLHg0
>>247
しつこいって、こっちから意見を述べたのはこれが最初なんだが??
PerlではどうたらをC++スレで押しつけようとしているおまえさんこそ
しつこそうだぞ
嫌なら出てけよ、余所者
0257デフォルトの名無しさん (ワッチョイ 4228-17Q5)
垢版 |
2022/11/25(金) 23:06:31.95ID:RzATrhyN0
> >>231
> ハッシュは数学的な関数で
> 辞書とは根本的に違うぞ
之大いに我が意を得たり

ハッシュ関数使わなくても連装配列実装できるもん遅いけど
ていうかハッシュが衝突したらそこから先は線形探索か何か(通常の実装では
なので連装配列をハッシュと呼ぶ風潮は嘆かわしいPerlerの端くれだけど
0260デフォルトの名無しさん (ワッチョイ 9f01-YdBL)
垢版 |
2022/11/26(土) 04:52:09.51ID:rUW0f5oN0
医学用語?
ネットスラングやぞw
----
ネットスラングなので明確な定義はなく、用法は人によるところだが、おおむね下記のような人間を指すことが多い。
■コミュニケーションが苦手(コミュ障):話や文章の理解力が乏しい、円滑な意思疎通が困難、空気が読めない、相手の感情を察知できない。
■拘りが強い:些細な間違いを指摘し揚げ足を取る、自分の作ったものに手を加えられるのを嫌う(ここやwikiで言う自治厨)、理想とするパターンをもっておりそれを邪魔されるとヒステリックになる。
■短気:上記のような過ちを指摘されると反射的に逆上する。
■独善的:ロジカルシンキングが出来ず自分が悪いという思考に思い至らない。
https://dic.pixiv.net/a/%E3%82%A2%E3%82%B9%E3%83%9A
0261デフォルトの名無しさん (ワッチョイ 9701-zuBb)
垢版 |
2022/11/26(土) 07:25:12.45ID:iOeKRej80
医師免許持ってないやつが診察するなよ。
0268デフォルトの名無しさん (アウアウウー Sa5b-zuBb)
垢版 |
2022/11/26(土) 10:07:14.70ID:B3T+QFuSa
最近の人はハッシュと言えば#しか思い浮かばんだろうから
perlの連想配列とか#hoge{'fuga'}とか描いてバグ理想
0270デフォルトの名無しさん (アウアウエー Sadf-/SwU)
垢版 |
2022/11/26(土) 10:19:15.89ID:qL7kB8pFa
perl界隈で連想配列のことハッシュとか言ってる人知らないな
何十年も前からみんな連想配列連想配列言ってたでしょ
最近はハッシュって呼ぶ人もいるのかな?

むしろRubyの方なら昔から組み込みライブラリに
その名も Hash っていうそのまんまのクラスがあるから分かるけど
0273デフォルトの名無しさん (アウアウエー Sadf-/SwU)
垢版 |
2022/11/26(土) 10:48:53.00ID:qL7kB8pFa
そうなん?(ヽ´ω`)

ちなみに手元のラクダ本1993年発行には

> P.37 この章の最後を締めくくる話題は連想配列である。
> 連想配列を自在に使いこなせるようにならなければPerlを究めたとは言えない。
> (略)連想配列を使えば(略)連想配列は(略)連想配列から(略)
> これが連想配列(略)連想配列も(略)連想配列全体を表すには(略)

とあるわ
0276デフォルトの名無しさん (アウアウウー Sa5b-zuBb)
垢版 |
2022/11/26(土) 11:00:18.64ID:B3T+QFuSa
>>272
>associative arrays of scalars, known as "hashes"

まともな英語力あるなら
連想配列が主でハッシュが副だと読めるだろ
0281デフォルトの名無しさん (ワッチョイ f77c-PVVO)
垢版 |
2022/11/26(土) 11:45:12.56ID:Q1Vkq5Eh0
hash table→associative array→map→dictionaryの順に抽象度が高い呼び方なだけで、どれが合ってるとか優れてるとかいう話じゃないね
hashは略し過ぎで誤解や混同を招くバカ丸出しの呼び方だと思うけど、それで定着しちゃってるバカ言語はしょうがないから使い続ければいいと思うよ
だからバカ言語erは帰ってくれないか
0286デフォルトの名無しさん (ブーイモ MMcf-/8MR)
垢版 |
2022/11/27(日) 10:42:16.60ID:Kt25DdLnM
std::setw は例えば整数 1 つ出力すると設定がリセットされますが std::setprecision
は持ち越されますよね

この辺の法則性というか思想みたいなものってありますか?一々調べるか試すかしかないですかね
0287デフォルトの名無しさん (ワッチョイ f77c-PVVO)
垢版 |
2022/11/27(日) 11:24:38.52ID:/D4jQIUG0
マニピュレータはストリームオブジェクトの状態を永続的に変えるのが基本的なコンセプトのはずだけど
なぜかsetwだけ例外で当初から叩かれてる
iostreamは色々と設計がいいかげんだからそういうものだと思って付き合うしかない
0288はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7f3e-Z2Iz)
垢版 |
2022/11/27(日) 11:45:00.03ID:VcW73S9v0
>>286
リセットというか厳密に言うと operator<< (または operator>>) のオーバーロードの内で width(0) を呼ぶことになっているものがある。
他に勝手に状態が変更されるものは書かれていないっぽいので例外的な処置だなぁ。
0290デフォルトの名無しさん (ワッチョイ 9f01-x1ca)
垢版 |
2022/11/27(日) 13:53:49.92ID:Tzlpv0SL0
> 自己紹介なんかしとらんよ
> ハッシュで恥かいたのはおまえだけだ
> 技術板でねらー語だけのレスしか
> できなくなってる惨めなザマ晒してろ
でっかいブーメラン刺さってんぞw
0291デフォルトの名無しさん (スププ Sdbf-tFPE)
垢版 |
2022/11/27(日) 14:00:32.19ID:Tmh9iNo1d
>>272
語るに堕ちるとはまさにこの事。
おまいの主張なら、
Perl has three built-in data types: scalars, arrays of scalars, and hashes.
と書かれていなければならない。
0302デフォルトの名無しさん (アウアウエー Sadf-/SwU)
垢版 |
2022/11/27(日) 16:53:39.58ID:MLqxhNeWa
どうでもいいのは十分承知
スレ違いも痛感してる

comp.lang.perlへの、とあるオッサンの投稿

https://groups.google.com/g/comp.lang.perl/c/NyYms98cjAY/m/BsGQNfVSZz8J?pli=1
> Doing linear scans over an associative array is like trying to club someone
> to death with a loaded Uzi.
> Larry

associative array( ー`дー´)キリッ
はいわかってますすみませんでしたこれで終わりです
0316デフォルトの名無しさん (スプッッ Sdbf-hkso)
垢版 |
2022/11/28(月) 12:40:00.21ID:W5LCj1xRd
operator[]できりゃ配列 VS 組み込み配列以外認めない
ファイ!
0319デフォルトの名無しさん (スプッッ Sd3f-Is/7)
垢版 |
2022/11/28(月) 18:40:08.47ID:M6XGVi6zd
配列とは有限の連続した区間の整数と
その整数に対応する数学的に導けるとは限らない値を
関連付ける辞書だ

ハッシュは任意の整数列から数学的に導かれる値だ

誰が何と言おうとどうにもならない違いがある
0320デフォルトの名無しさん (ササクッテロロ Spcb-bAlK)
垢版 |
2022/11/28(月) 18:51:48.08ID:0bwybHojp
配列ってポインターの劣化版だろ?
0331デフォルトの名無しさん (ササクッテロロ Spcb-bAlK)
垢版 |
2022/11/28(月) 20:28:41.55ID:GDVe/V0ep
程よく刻んで一定長の値になるから
分類キーにしたりするんだろ?
0334デフォルトの名無しさん (ササクッテロロ Spcb-bAlK)
垢版 |
2022/11/28(月) 20:55:34.01ID:pf+ZrZrvp
配列やポインターの指してる中身が何かは今関係ないんだがなぁw
0335デフォルトの名無しさん (アウアウエー Sadf-/SwU)
垢版 |
2022/11/28(月) 21:53:05.48ID:iNOjxk3Aa
ちなみにJavaならハッシュって言うと
java.util.Hashtableよりも
java.lang.Object#hashCode()の話に聞こえちゃうよね(;^ω^)
あとどんな型でも配列にできるんだから
ポインタの配列を「ポインタ配列」などと区別して呼ぶのは珍妙よね

>>325
ココイチのハッシュドビーフうまいよね
0341はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7f3e-Z2Iz)
垢版 |
2022/11/28(月) 22:40:32.85ID:26iHAu1B0
ハッシュテーブルの実装に配列を使うのはごく普通のことなので「∃配列 ∈ハッシュテーブル」とは言える。
それを縮めて「配列がハッシュ」と表現する程度のことは文脈によっては自然言語的にはまあ珍しくは無い程度のもんだろ。
よくない表現だとは強く思うけどもあり得ないというほどではないんじゃないの。
0344はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7f3e-Z2Iz)
垢版 |
2022/11/28(月) 22:54:19.16ID:26iHAu1B0
繰り返すけど良くはないよ。
良くはない言い回しだけど自然言語ではその程度のブレは有るものなんだから
ある程度は前後の状況で察していくしかしょうがないだろう。

まあ今回は察した結果として最初に言い始めたやつはなんか勘違いしているっぽくはあるとは思うけど。
0347デフォルトの名無しさん (ワッチョイ 5701-L9hK)
垢版 |
2022/11/28(月) 23:15:54.31ID:gEsuPeHf0
USBメモリをUSB
携帯電話を携帯
0348デフォルトの名無しさん (ワッチョイ 9701-zuBb)
垢版 |
2022/11/29(火) 00:38:09.61ID:michHh0F0
>>341
C++の配列はハッシュと全く別のものですよ。
混同しないほうが良いです。
0356デフォルトの名無しさん (ワッチョイ 9f01-YdBL)
垢版 |
2022/11/29(火) 09:40:28.73ID:4MUOq3YH0
いわゆる要約関数と暗号学的ハッシュ関数は関連はあるけど用途が違う
どっちの関数の話かはたいてい文脈でわかるんだがたまに>>354みたいにハッシュという言葉だけに反応する奴が話をややこしくする
0363デフォルトの名無しさん (アウアウウー Sa5b-yYU6)
垢版 |
2022/11/29(火) 17:27:05.61ID:USqQ0Gkfa
自然言語的にはそれくらいの幅があるってのには一理あるけど、
連想配列をハッシュ関数使ってなくても何でもハッシュと呼ぶのって
ゲームできる機械なら何でもファミコンって呼ぶのと同じくらいハズいよな。
0364デフォルトの名無しさん (ワッチョイ f77c-PVVO)
垢版 |
2022/11/29(火) 17:49:05.07ID:0jENVbSE0
伝わるか伝わらないかで言えばまあ伝わるから、あとは言った人間が恥かくだけの問題
だからそれでいいんだ正しいんだってダダこねれば恥の上塗りするだけ
それで何とも思わないなら別にいいんじゃないの好きに呼べば
0366デフォルトの名無しさん (ワッチョイ 9f01-YdBL)
垢版 |
2022/11/29(火) 18:43:14.51ID:4MUOq3YH0
>>363-364
まだやるの?
誰もPerlでの呼び方が良いなんて言ってなくて単に事実として公式ドキュメントでそう呼ばれてると言うだけの話なのでこんな所で恥ずいとか言ってないで公式に言ってやれよw
0371デフォルトの名無しさん (ワッチョイ 97f0-mcXv)
垢版 |
2022/11/29(火) 21:32:48.74ID:18+vW8PY0
誰が馬鹿なのかなんて一目瞭然なんだから落ち着いてきたところで基地外に餌やるのやめなよ…
0372デフォルトの名無しさん (US 0Hab-yy58)
垢版 |
2022/11/29(火) 21:33:00.88ID:gIuDQpHWH
役に立つレスは >.277 のみ

Map的なものに対する呼び方で
その人のバックグラウンドが透けて見えて少し面白いよね
map ←C++
連想配列 ←Perl
Hash ←Ruby
Map, Hashtable ←Java
Dictionary, Hashtable ←C#
0373デフォルトの名無しさん (ワッチョイ 9f01-YdBL)
垢版 |
2022/11/29(火) 21:34:00.99ID:4MUOq3YH0
>>370
> 配列はハッシュではない
> おまえがそこでいくら粘っても覆ることは絶対にない
バカは人の話を聞いてないのか、それとも理解できないのか...

>>319
> 誰も同じなんて言ってないぞ、頭大丈夫?w
0376デフォルトの名無しさん (ワッチョイ 9701-zuBb)
垢版 |
2022/11/29(火) 22:51:06.76ID:mBDoFEuP0
mapをhashと呼ぶのもAUTOだぞ。
0381デフォルトの名無しさん (ワッチョイ 9fad-RPwI)
垢版 |
2022/11/30(水) 01:07:45.84ID:TaPBZKHt0
仮想メモリのアドレス番号それ自体がハッシュの一種であるにより、ただの配列もハッシュであると断言できる
0385デフォルトの名無しさん (アウアウウー Sa5b-FutQ)
垢版 |
2022/11/30(水) 08:19:43.48ID:SGXzBjU4a
配列がハッシュだってのは、a[0]とa[1]は0とか1っていうアドレスにあるわけじゃなくてaとかa+(型サイズ)のアドレスにいるってことでしょ
0392デフォルトの名無しさん (アウアウウー Sa5b-zuBb)
垢版 |
2022/11/30(水) 11:15:38.95ID:D6E9fHT2a
HAGEYO
0395デフォルトの名無しさん (ワッチョイ 9701-zuBb)
垢版 |
2022/11/30(水) 18:59:26.64ID:YZNvxpbg0
PerlでC++にマウントですと!?
0407デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/01(木) 11:33:26.84ID:K0S28fMrM
ハッシュというのは、ある種のデータ構造の一種に名付けられた名前で、
検索を速くするためにハッシュ値を使う方式。
unsigned int hash = CalcHash(key);
でハッシュ値を計算し、
Node *p_hash_table[hash];
でデータのリストに即座にたどり着くような方式。
普通に線形検索する場合と比べて検索が劇的に速くなる。
なので連想配列が必ずハッシュ方式であるとは限らない。
また、配列はコンピュータ科学ではメモリー上でデータを連続的に隣接して配置する
単純なデータ構造に名付けられたものであって、ハッシュ構造(方式)とは区別されている。
0408デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/01(木) 11:39:01.75ID:K0S28fMrM
>>407
訂正:
誤: Node *p_hash_table[hash];
正:
constexpr unsigned int HASH_MAX = 4096;
Node *p_hash_table[HASH_MAX];
・・・
// 典型的なハッシュ方式による検索関数 :
Node *SearchData(string &key) {
 unsigned int hash = CalcHash(key); // とても高速にkeyに対するハッシュ値を計算。
 Node *pNode = p_hash_table[hash]; // 同じhash値に属する全てのNodeのリンクリスト
 while (1) {
  if (pNode->key == key) {
   return pNode;
  }
  pNode = pNode->pNext;
 }
}

テキトーに書いたのでまだ書き間違いが残っているかも知れないが、大体こんな感じ。
0409デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/01(木) 11:42:25.52ID:K0S28fMrM
>>408
[補足]
連想配列に良く使われる方式には、大きく分けて二つ有る:
1. ハッシュ構造 >>408 参照。
2. バランス木(赤黒木、B木(2,3,4木など)、AVL木)

C++では、
1は、map、set、multimap、multiset
2は、unorderd_map、unorderd_set、unorderd_multimap、unorderd_multiset
0415デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/01(木) 14:11:29.45ID:cs2lswThM
>>414
MD5などのハッシュとハッシュ法の役割や目的が結構違いまっせ。
前者はデータが改竄されてないかをチェックするために用い、
後者は検索・探索の高速化のために用いる。
恐らく、もとは後者から用いられ始めたのだと思う。知らないけど。
0417デフォルトの名無しさん (ワッチョイ 5701-L9hK)
垢版 |
2022/12/01(木) 15:09:39.09ID:9MCw0pWF0
>>227が最初だからおまいらもう1週間もやってるんだなw
スレの途中を読む気もしないので論点も把握してないのだが
C++にはstd::hashがあるので用語は厳密に使う必要があるとは思う
0428デフォルトの名無しさん (ワッチョイ 9701-zuBb)
垢版 |
2022/12/01(木) 19:12:45.42ID:mPKw+fm50
ハッシュのおかげで今週は皆楽しかっただろ。
ちゃんとお礼言っとけよ。
0431デフォルトの名無しさん (ワッチョイ 9701-zuBb)
垢版 |
2022/12/01(木) 22:28:42.84ID:mPKw+fm50
ハッシュは配列のことだろ?
0433デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/02(金) 00:20:40.99ID:h6/3aIZ1M
>>416
英語の辞書でhashを引くと、「細切れ」「細かく切る」と出てくる。
これは、検索を高速化するためのHash法のHashテーブルが細かく切って
データを格納していることと対応しているようだ。
つまり、Hashという言葉の由来はこのHash法から来ていると推定できて、
Hash関数や、Hash値という言葉もHash法由来のはず。
だから、MD5などのHash値は、Hash法よりも後発のはず。
つまり、Hashというのは、もともと「Hashデータ構造」に対応していて、
MD5などの値を「Hash値」と呼ぶのは「あとづけ」と考えられる。
0434デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/02(金) 00:33:19.34ID:h6/3aIZ1M
>>433
[補足]
何が言いたいかというと、もともとHashという言葉は、Hash法由来で、
Hash値という言葉も、Hash法から来ていて、
Hash値やHash関数が先でHash法が後、ということ「ではない」。
Hash法を実現したいために、Hash値を求める方法が工夫された。
Hash法 ---> Hash 値 (by Hash関数)
が正しい起源。
もう一度言う、Hash値を使っているからHash法なのではない。
Hash法を実現するために作る値がHash値。
0437デフォルトの名無しさん (ワッチョイ 9f28-9ylf)
垢版 |
2022/12/02(金) 00:45:49.71ID:eNwFIhhK0
>検索を高速化するためのHash法
しかしねえハッシュは本来は実用的なメモリ使用量でメモリに乗りきらないサイズの集合の要素を取り扱うためのしくみなのだから、
入力集合の全単射写像ならハッシュにする意味が無いのだから、
検索を高速化する用途の方が後付けなのだから、
0438デフォルトの名無しさん (ワッチョイ 9f28-9ylf)
垢版 |
2022/12/02(金) 00:48:00.35ID:eNwFIhhK0
ウィキの冒頭にあるようにハッシュというのは検索というよりは区別のためのしくみなのだから、
MDとかSHA-1とかの方こそが本来の意味でのハッシュなのだから、
0440デフォルトの名無しさん (ワッチョイ ffcf-ykd8)
垢版 |
2022/12/02(金) 00:50:49.40ID:VfaFcsHC0
Perl のハッシュは、もともとは連想配列 (associative array) という名前で呼ばれていましたが、
この名前は長すぎるので、1995 年頃に、Perl コミュニティの中でハッシュ (hash) と呼ぼうということになりました。
Perl5 の時代からはハッシュと呼ぶことになっています。
ハッシュという名前は、連想配列の「実装」に使われるハッシュテーブル (hash table) に由来しています
以上、あくまでもPerl コミュニティの話で、他のコミュニティで流用したら、こんな風にひと悶着起こすわけです
0442デフォルトの名無しさん (ワッチョイ 9f28-9ylf)
垢版 |
2022/12/02(金) 01:06:10.28ID:eNwFIhhK0
どういうことかというとxの検索ではxそのものが取り出されねばならないからxのハッシュはxの検索を利用するユーザーからは見えないから脇役
(別段ハッシュを使わない検索手段で実装してもユーザーにはそれはわからない

一方MD5とかSHA-1とからは長いデータが実用的に無視できる確率でしか衝突しない短いハッシュになるというのがウリなので
MD5とかSHA-1を利用するユーザーはMD5とかSHA-1とかのハッシュそのものを目の当たりにするという違いがある、

というしくみ、
0443デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/02(金) 01:47:39.50ID:h6/3aIZ1M
>>437
>検索を高速化する用途の方が後付けなのだから、
Hashが「細かく切る」という意味なのだから、その説は何かおかしい。
細かく切ることによって検索を高速化したものがHash法なのであって。
0445デフォルトの名無しさん (オイコラミネオ MMab-/SwU)
垢版 |
2022/12/02(金) 02:17:32.59ID:h6/3aIZ1M
>>444
Wikipedia英語版のHash tableの項目を見てみると、
The idea of hashing arose independently in different places.
In January 1953, Hans Peter Luhn wrote an internal IBM memorandum
that used hashing with chaining. Open addressing was later proposed
by A. D. Linh building on Luhn's paper.[7]: 15 

となっていて、「hashing」がhash tableの概念をそのまま対応していると
考えられる。hashingのアイデアそのものがhash tableのために生み出されたようだ。
0446デフォルトの名無しさん (ワッチョイ 9701-zuBb)
垢版 |
2022/12/02(金) 07:20:08.20ID:DFt0sUTo0
要約すると、ハッシュ法とは配列のことで良いだろ?
0452デフォルトの名無しさん (ワッチョイ f79c-YdBL)
垢版 |
2022/12/02(金) 16:13:02.65ID:ahpGcODy0
ハッシュはキー長固定が前提だけど、配列は(概念的には)固定長前提では無いので、この2つを同一視するのは無理がある。

そもそも配列にキー衝突の概念無いだろ。
配列の場合、キーが異なれば衝突しない。
0458デフォルトの名無しさん (オイコラミネオ MMab-+AMV)
垢版 |
2022/12/02(金) 18:29:46.96ID:l1cskCXdM
>>452
数学的概念としては、独自に同一視して理論を展開することも可能だが、
そもそも、配列のa[idx]はマシン語の1命令でアクセスできて、1クロックなのに
対して、ハッシュの x[key]は、150クロック〜数千クロック程度かかる。
(少なくとも後者はCPUで1命令(1クロック)では処理できない。)
0462デフォルトの名無しさん (アウアウウー Sa5b-tFPE)
垢版 |
2022/12/02(金) 20:50:07.24ID:mpDpMcgja
シッタカが自爆するスレ
0464デフォルトの名無しさん (ワッチョイ d75f-JadS)
垢版 |
2022/12/02(金) 21:26:41.80ID:OAAJQcGw0
Pythonで経過時刻を測る場合、以下のような方法を使いますが
C++でPythonと同じ計測手法を使うにはどうしたら良いですか?

import time
startTime = time.time()
nowTime = time.time() - startTime
print(nowTime)
0467デフォルトの名無しさん (ワッチョイ d75f-JadS)
垢版 |
2022/12/02(金) 21:33:56.38ID:OAAJQcGw0
>>465
Windows限定で使用する予定です。
0474デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/03(土) 01:21:25.79ID:dPKr1JJoM
>>463
要は、JSなどで配列とHash法が同じ書き方が出来るが故に、Hash法が
「配列」みたいには高速ではないということを知らない人が居るのではないかと
思って書いただけ。
x86系の場合、配列は、要素サイズが1,2,4,8の時はa[i]がマシン語の1命令で
1クロック、それ以外の一般サイズだと2命令で、今のCPUだと、
4クロック〜20クロック程度。
ハッシュ法だと、keyが10文字の文字列の場合で、最低でも、まあ、100クロック位
はかかると見ておいたほうがいい。最高だと上限は無いが、まあ、数千〜数万
クロック程度になると考えた方がいい。
これは、マシン語まで見たときの常識的な間隔。
0476デフォルトの名無しさん (ブーイモ MM5e-mM0k)
垢版 |
2022/12/03(土) 08:52:01.00ID:+FzzA9JIM
0 以上 64 以下の整数 n に対して 2^n-1 (ビットごとの排他的 OR 演算子ではなく累乗の意味 2**n-1 です)を std::uint64_t 型で返す関数って場合分け無しでスッキリ書けませんかね?
0478デフォルトの名無しさん (ワッチョイ 8a28-BV3Z)
垢版 |
2022/12/03(土) 09:23:14.36ID:qMCuKdke0
std::uint64_tの加算オーバーフロー時の挙動がunsigned intと同様にwrap aroundなんなら普通に
std::uint64_t foo(const int n) { return ((std::int64_t)1 << n) - (std::int64_t)1; }
で良くねconstexpr的な何かとかでマズい?
0479はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv)
垢版 |
2022/12/03(土) 09:26:37.99ID:riW5om/o0
すまぬ。 >>477 だと n が 0 のときは未定義なのでそれだけ場合分けが必要になってしまうな。
だからといって (std::uint64_t(1) << n) - 1 だと 64 のときが駄目だし、
場合分け無しという条件だと思ったよりめんどいかも?
0480デフォルトの名無しさん (ワッチョイ 8a28-BV3Z)
垢版 |
2022/12/03(土) 09:43:52.56ID:qMCuKdke0
違った加算オーバーフローの話やなかったorz

シフト演算については
If E1 has an unsigned
type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable
in the result type.
E1 が符号なし型を持つ場合、結果の値は、E1 * 2E2 の、結果の型で表現可能な最大値より 1 大きい値を法とする剰余となる
なので言語規格上は (uint64_t)1 << 64は合法なはず……
0481デフォルトの名無しさん (ワッチョイ 8a28-BV3Z)
垢版 |
2022/12/03(土) 09:49:24.58ID:qMCuKdke0
訂正orz
誤: 2E2
正: 2**E2 (2のE2乗)

符号付きの型はオーバーフローで例外を発生するアーキテクチャーがあるから
表現できるビット数からあふれるコーディングは未定義動作か何かやが
符号無し型はモジュロ演算になるから溢れてもおk
と言う印象(記憶モード
※ 個人の感想です
0483はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv)
垢版 |
2022/12/03(土) 10:15:30.26ID:riW5om/o0
std::bitset を経由すれば大丈夫だということを発見した。

std::uint64_t((compl std::bitset<64>(0)>>(64-n)).to_ullong())

これを「スッキリ」といえるかどうかは微妙なところかもしれぬ……。
0484デフォルトの名無しさん (ワッチョイ 8a28-BV3Z)
垢版 |
2022/12/03(土) 11:26:23.20ID:qMCuKdke0
>>482
わかりた
ではこう汁、
 指数 n == (n/2) + (n/2) + (n & 1) ※ 除算は結果の小数以下切り捨て
ので
 2**n - 1 = 2**((n/2) + (n/2) + (n & 1)) - 1
 = 2**(n/2) * 2**(n/2) * 2**(n&1) - 1
よって
 std::uint64_t foo(const int n) {
  const std::int64_t x = (std::uint64_t)1 << (n / 2);
  return (x * x * ((std::uint64_t)1 << (n & 1)) - (std::int64_t)1;
 }
でだいたいおk、
0485デフォルトの名無しさん (ワッチョイ 2647-fbc4)
垢版 |
2022/12/03(土) 11:32:11.79ID:D7LggL4j0
n?1ull<<(n-1):0
0489デフォルトの名無しさん (ワッチョイ 9fc2-4FAg)
垢版 |
2022/12/03(土) 21:09:42.26ID:WYd/d9iJ0
>>457
今さら知らなかったとは言えなくて
元々知ってた別人になるしかないもんな

それほどまでに恥ずかしいことだからw

# さあ、おまえが別人かどうかの判断は衆目に任せよう
0491デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/03(土) 23:46:07.24ID:mCv82Mp+M
ところで、C++でも、Javab磴#でも、メモャ梶[不足例外を封竭ォしない風潮bノなっている
ようです。それは、メモリー不足が起きる可能性があるところの、
文字列合成やコンテナ要素追加が簡単に書けるようになった反面、
その全ての箇所でエラー処理をするのはめんどくさすぎるという
事情から来ていると思います。
しかし、テキスとエディタなどで、一文字や一行追加した時にメモリーが確保できない
場合に、「メモリーが一杯です」などと表示することはMS-DOSならよくあったことで、
そのような場合にメモリー不足例外を補足する事は原理的には可能です。
いまや、そのような場合のメモリー不足はほぼ起き得なくなってますが、エラーを感知
しないで本当に良いと思われますか?
もっと進めれば、メモリー不足例外は、商用アプリでも「完全無視」を決め込んでも良いと
思われますか?
0492デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/03(土) 23:47:44.27ID:mCv82Mp+M
>>491
携帯SIMを使っているので電波にエラーが生じたらしいです:
誤:ところで、C++でも、Javab磴#でも、メモャ梶[不足例外を封竭ォしない風潮bノなっている
正:ところで、C++でも、JavaやC#でも、メモリ不足例外を補足しない風潮になっている
0493デフォルトの名無しさん (ワッチョイ 8a28-BV3Z)
垢版 |
2022/12/04(日) 00:02:09.11ID:r/mQBEYb0
>エラーを感知 しないで本当に良いと思われますか?
良い
どうせメモリ不足になったら有効なことはほとんど何もできない

ただしそのかわり処理の不意の中断から絶対に保護すべきリソースとか絶対動かしたままにしてはいけない処理は
例外安全なクラスで管理して確実にクローズ処理せねばならない

jこれはメモリ不足の状況でも同じで、そういうのはヒープを使わないで書くのが最善やが、
内部でヒープを使うライブラリに依存している等でヒープをどうしても使わざるおえないの場合は
事前malloc()→例外捕捉時に解放、というテクが昔からあっる
0494デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 00:02:21.62ID:BcAMllhiM
スタック的な(?)コンテナで、pop_back()メソッドは戻り値が void型で、
つまり、pop したデータを返しませんが、BJ. stroustrup氏によれば、
それもreturn文で要素をコピー(?)する際に、メモリー不足例外が起きる
可能性考慮したとのことです。
どうしてmoveじゃ駄目なのかもし分かりませんでしたが。
0495デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 00:04:34.95ID:BcAMllhiM
>>493
>どうせメモリ不足になったら有効なことはほとんど何もできない
MS-DOSの時、テキストエディタなどではメモリー不足になると、
ちゃんとメッセージを出して、なおかつ、その後もメモリーが無い割には
安定動作してました。
0496デフォルトの名無しさん (ワッチョイ aa01-QZbE)
垢版 |
2022/12/04(日) 00:11:51.06ID:S/+N28Tr0
>>489
まだ粘着してるのかよ...
本人だと思いたいんならそれでいいんじゃね?
おれが本人かどうかに関わらずお前が>>231で本人が謝ってるのにしつこく>>227に粘着するクズであることは確定したし
まあもうそうするしかないんだろうけどw
0497デフォルトの名無しさん (ワッチョイ 8a28-BV3Z)
垢版 |
2022/12/04(日) 00:17:03.45ID:r/mQBEYb0
>>494
x = queue.pop();
というのを許すキューの仕様だと
とキュー上のx'とそのコピーxが同時に存在するタイミングが一瞬生じてメモリ不足になりかねないという>>494の懸念の他に、
コピコンが呼ばれる時間の無駄がある

xにムーブコンストラが定義してありqueue.pop()をムーブ対応に設計したとしても
ムーブコンストラクタが呼ばれる時間の無駄は相変わらず存在する

最も効率が良いのはpop()するタイミングまでキュー上のオブジェクトの参照を返し、
pop()するタイミングではキュー上のオブジェクトの破棄のみ行うという現行のインターフェース、
0499デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 00:31:29.29ID:BcAMllhiM
>>497
>x = queue.pop();
>というのを許すキューの仕様だと
>とキュー上のx'とそのコピーxが同時に存在するタイミングが一瞬生じてメモリ不足になりかねないという
よく分かりません。できればもっと詳しくお願いできませんか。
キュー上の x' を x に move すれば駄目なのでしょうか?

>xにムーブコンストラが定義してありqueue.pop()をムーブ対応に設計したとしても
>ムーブコンストラクタが呼ばれる時間の無駄は相変わらず存在する
>最も効率が良いのはpop()するタイミングまでキュー上のオブジェクトの参照を返し、
>pop()するタイミングではキュー上のオブジェクトの破棄のみ行うという現行のインターフェース、

なるほど、参照で返すのは効率がよいのは分かりますが、stroustrup氏によれば、moveは
速いと主張されているわけです。
私はmoveより参照の方が効率が良いと常々思っておりましたが。
彼はmoveが大好きなはずなのですが。
0501デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 00:41:37.02ID:BcAMllhiM
>>500
>ムーブコンストラが呼ばれる時間の無駄がある(2回目
なるほど、ならば、スタックポインタだけ元に戻して、値は捨ててしまう
バージョンの pop を用意すれば良いだけでは無いですか、今みたいに。
0502デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 00:43:51.82ID:BcAMllhiM
>>501
Strousstrup氏によると、メモリー不足になって例外が生じた場合の
対処が難しい、みたいなことを言っていたと思います。
しかし、moveコンストラクタ/代入を使った場合にはメモリー不足も生じませんし、
moveコンストラクタ/代入は例外を生じさせてはいけない、と彼自身は
普段から何度も言及していたと思うんです。
0503デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 00:49:09.96ID:BcAMllhiM
>>502
仮にstackの要素クラスにコピーコンストラクタしかない場合は、メモリー不足が
生じてstd::bad_alloc 例外がthrowされる場合があるとは思いますが、難しい
とは言ってもそれが生じた場合に対処が全く出来ないとは思えません。
あるとすれば、要素がmoveコンストラクタを持っている場合でも、
try catch ブロックを書くことで、オーバーヘッドが生じる
場合があることを彼は恐れていたのでしょうか。
0504デフォルトの名無しさん (ワッチョイ 8a28-BV3Z)
垢版 |
2022/12/04(日) 01:11:37.29ID:r/mQBEYb0
>>501
ムーブしたかったらqueue.front()が返す参照でキュー上のx'をxか何かにムーブするだけ(※1)で良くね↑?
 x = std::move(queue.front());
 queue.pop_front();

※1: xやx'のクラスにムーブコンストラの定義は必要

>スタックポインタだけ元に戻して、値は捨ててしまう
>バージョンの pop を用意すれば良いだけでは無いですか、今みたいに。
ムーブするpop_front()と、デストラクタを呼ぶだけの今のpop_front()がどこが同じなのかkwsk、
0506デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 01:33:30.77ID:BcAMllhiM
>>504
マシン語の「pop命令」は伝統的に、スタックポインタを戻すことと、値を読み出すことを
同時に行っていました。
C++の設計では、値の読み出しと、スタックポインタを戻すことが分かれており、命名も
変なのです。
つまり、2つの事を合体させて行なうのが伝統的に「pop」であった伝統や習慣とは
異なる命名をC++はとってしまっているので、心理的に受け入れがたくなっているわけです。
0507デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 01:50:30.99ID:BcAMllhiM
>>506
例えば、Rustのpopは、ちゃんとマシン語の伝統と同じく、
戻り値が読み出された値になっていて、かつ、スタックポインタも戻ります。
C++のはどうしてこうなったのか、と思うように伝統を破ってます。
伝統を知らない人が作ったかのように。
0509デフォルトの名無しさん (ワッチョイ d8cf-R4o2)
垢版 |
2022/12/04(日) 02:03:07.32ID:qWdYVkpM0
C++だけでなく、いくつかの言語で、配列にアクセスするのに
push() pop() といった名前の関数があるから、その流れじゃないの
対象はあくまでも配列であって、cpu のスタックとは色々異なるわけだし
そこでどこまでスタックぽく扱うかは、言語の仕様というか設計者のお好みによるというかw
0511デフォルトの名無しさん (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/04(日) 02:22:20.52ID:BcAMllhiM
>>510
自己レスですが、
https://stackoverflow.com/questions/25035691/why-doesnt-stdqueuepop-return-value
これですかね。
[Q] Why doesn't std::queue::pop return value.?
[A]
・・・
So, whats the difference, pop function could have done the same thing.

It could indeed have done the same thing. The reason it didn't, is because a pop that returned the popped element is unsafe in the presence of exceptions (having to return by value and thus creating a copy).

Consider this scenario (with a naive/made up pop implementation, to ilustrate my point):

template<class T>
class queue {
T* elements;
std::size_t top_position;
// stuff here
T pop()
{
auto x = elements[top_position];
// TODO: call destructor for elements[top_position] here
--top_position; // alter queue state here
return x; // calls T(const T&) which may throw
}
If the copy constructor of T throws on return, you have already altered the state of the queue (top_position in my naive implementation) and the element is removed from the queue (and not returned). For all intents and purposes (no matter how you catch the exception in client code) the element at the top of the queue is lost.

This implementation is also inefficient in the case when you do not need the popped value (i.e. it creates a copy of the element that nobody will use).

This can be implemented safely and efficiently, with two separate operations (void pop and const T& front()).
0513デフォルトの名無しさん (ワッチョイ 3602-WJTY)
垢版 |
2022/12/04(日) 11:36:02.70ID:flilPTWf0
0〜255しか格納されないことが保証されている変数aがあって
その変数の値を以下のイメージのように判定する効率的なやり方はないでしょうか
a == {8, 9, 12}
aが{ }内のいずれかの値に該当しているかどうかを判定したいです
{ }はあらかじめ定数でもよいです
0517デフォルトの名無しさん (ワッチョイ c001-g9pY)
垢版 |
2022/12/04(日) 12:07:00.75ID:JyCGAu5J0
std::bitset<256>はどうですか?
0520513 (ワッチョイ 3602-WJTY)
垢版 |
2022/12/04(日) 17:30:39.25ID:flilPTWf0
いろいろ例をありがとうございます
pascalからの移行で集合型をどうにか再現できないかと試している中での質問でした
pascalの集合型なら[8, 9, 12](8, 9, 12は一例で、本来は任意の値を指定したい)を
直接使えて便利なので多用していました

アドバイスのおかげで比較は近いことを再現できましたが、
それとは別のケースで[8, 9, 12]を直接関数の引数で指定する方法を探しています
引数で指定する際の値の範囲は0〜31を超えることはなさそうなので
ビットを立てた整数を返す、可変長引数を取る関数を作れば良さそうだと思いました
0522513 (ワッチョイ 3602-WJTY)
垢版 |
2022/12/04(日) 17:49:59.78ID:flilPTWf0
std::bitset<256>も試してみましたが
{8, 9, 12} こういった形式単独で使えるやり方はないかと調べていました
0523はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv)
垢版 |
2022/12/04(日) 18:04:56.88ID:YO7rrhiC0
std::bitset は unsigned long long を受け取るコンストラクタには constexpr が付いてるので
それより小さいビット数の bitset についてならコンパイル時に計算してしまうことも出来る。
0524はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv)
垢版 |
2022/12/04(日) 18:39:41.91ID:YO7rrhiC0
たぶんやりたいのはこういう感じかな。 (想定は C++17 以上)

#include <bitset>
#include <cassert>
#include <climits>
#include <cstddef>
#include <type_traits>

template <std::size_t N = sizeof(unsigned long long int) * CHAR_BIT, class... T>
constexpr std::enable_if_t<(sizeof...(T) <= N), std::bitset<N>>
make_flagged_bitset(T... args) noexcept {
return std::bitset<N>(((1ULL << args) | ...));
}

// 使用例
int main(void) {
constexpr auto table = make_flagged_bitset(8, 9, 12);
// セットしてないところは偽値
assert(table[0] == false);
assert(table[1] == false);
assert(table[10] == false);
assert(table[20] == false);
// セットしているところは真値
assert(table[8] == true);
assert(table[9] == true);
assert(table[12] == true);
}
0525513 (ワッチョイ 3602-WJTY)
垢版 |
2022/12/04(日) 19:19:16.77ID:flilPTWf0
>>524
やりたいことのイメージにすごく近いです
思いもつかない難しい構文で勉強になります
内容を理解して使わせていただきます
ありがとうございました
0527はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv)
垢版 |
2022/12/04(日) 20:05:21.16ID:YO7rrhiC0
>>525
念のために繰り返すけど >>524>>523 で述べた性質があるので 64 までしか保証されないし、
エラーチェックをあまり頑張ってないので使い方を間違えたときに捕捉されないかもしれない。
あくまでもおおざっぱにはこういう考えかたでいけるだろうというサンプルだからそのつもりで。
0529513 (ワッチョイ 3602-WJTY)
垢版 |
2022/12/04(日) 23:12:00.77ID:flilPTWf0
これまでビット演算を意識したことがなかったので考え方を知れて助かります
提示いただいた例から自分でも調査が進められそうでなんとかなりそうです
いろいろありがとうございました
0535デフォルトの名無しさん (ワッチョイ 9fc2-He5u)
垢版 |
2022/12/05(月) 13:51:14.89ID:0xhTnbB50
速度重視なら>>518だろ
メモリ食うけど、つーてもキロバイト未満だし
古いワンチップマイコンとかじゃなきゃ微々たるもん
ハードできる人ならワイヤードロジックって手もある
0538はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv)
垢版 |
2022/12/05(月) 14:25:03.89ID:6Xcp09rU0
集合を扱うには std::set を使うのが楽だと思う。
集合を集合っぽく扱える機能は一通りそろってるからたぶん集合型というものに期待していることはだいたい含まれるよ。
Pascal の集合型のことはよう知らんけど。

(一般的に) std::set は二分木で実装されるという都合上、やりたいことによっては性能 (速度) 上の不満が生じることもあるかもしれないけど、
具体的な問題が出る前に先回りして考えてもだいたい徒労だしな。

>>537
実行時にロケールを切り替える必要性からじゃない?
0539デフォルトの名無しさん (ワッチョイ aa01-QZbE)
垢版 |
2022/12/05(月) 14:43:13.12ID:9YGPhFSH0
>>537
今でもそうじゃないの?
>>520 > 引数で指定する際の値の範囲は0~31を超えることはなさそうなので
と言う条件だからビット演算の方が早いかもって話であって 、-1~255の範囲ならたいていの環境でテーブル引くのが最速だと思う
0541513 (ワッチョイ 3602-g9pY)
垢版 |
2022/12/05(月) 15:16:20.05ID:jV16hsjJ0
0〜255を格納する方は定数でしか使わないので>>518のやり方にしました
0〜31くらいまでしか使わない方は、変数に格納された任意の値の集合を
そのまま引数に渡したり、積集合や差集合を求めるのを想定しています

確かにstd::setがその用途ですね
速度が遅そうで敬遠していましたが、実際にはこれがボトルネックになることはないと思います
initializer_listと合わせれば、ほぼPascalと同じ使用感でいけるので、ビット演算のテクニックは
引き続き研究しつつ、いったんstd::setで実装しようと思います
0543530 (オイコラミネオ MM71-NwO+)
垢版 |
2022/12/05(月) 17:26:36.58ID:rfCFGpMmM
>>540
キャッシュの話になると本当の速さがなかなか分からなくなってくる。
(CPUアーキテクチャやその他の処理の仕方に依存してしまうし。)
キャッシュがある CPU において、キャッシュミスが発生した場合は、
>>526の方が速いであろうと予測はされる。

そもそも、キャッシュの働きが弱いラズパイPICO、Arduino、ESP32 などでは
恐らく>>518 の方が速い。
そもそもシフト演算がシフト量に比例して遅くなるマイコンもあるだろうし。
Z80や8086はそうだった。

x86、x64の場合、
この関数を使うループの中で、他の目的のためにメモリーを大規模に使った場合は、
>>526の方が速いが、沢山メモリーを使わなかった場合は、>>518の方が速い。
0544513 (ワッチョイ 3602-g9pY)
垢版 |
2022/12/05(月) 17:29:22.78ID:jV16hsjJ0
std::setは集合演算が思った使い勝手ではなかったです
>>526と列挙型を組み合わせることにしました
長々とスレを消費し申し訳ありませんでした
どのレスも参考になり助かりました
0559デフォルトの名無しさん (スッップ Sd70-AXrT)
垢版 |
2022/12/06(火) 15:56:04.19ID:iX2JPZR5d
HDDを指さしてメモリと言ってたやつのほうがまだマシ
記憶装置という点でそんなに大外れではないからな

配列を指さしてハッシュと言うやつは
アメリカザリガニを指さして飛行機と言うようなもんで
どうやっても擁護不可能
0567デフォルトの名無しさん (ワッチョイ 9fc2-He5u)
垢版 |
2022/12/06(火) 21:47:51.22ID:63yxghiR0
>>565
何? 謝罪したらこんなに恥をかかずに済んだってとこに、まだすがりたいの?
そりゃそうだろうね、技術板で最大の恥をさらしたんだからwww

おまえ悪態つきすぎたんだよ、こっちも悪意に満ちた対応するからな
もう覚悟するしかねえんだよ、おまえw
0568デフォルトの名無しさん (ササクッテロラ Sp5f-w5YM)
垢版 |
2022/12/06(火) 21:59:01.18ID:Pw6mR/Vsp
粘着恥ずかしいw
0569デフォルトの名無しさん (ワッチョイ c001-g9pY)
垢版 |
2022/12/06(火) 22:07:01.02ID:iea0dAEs0
C++使いは、その程度のことで粘着しない。
なぜなら、C++使いは爺だから。
0573デフォルトの名無しさん (ワッチョイ c001-g9pY)
垢版 |
2022/12/06(火) 23:07:03.02ID:iea0dAEs0
インテリ爺は粘着される方だろ。
0578デフォルトの名無しさん (スププ Sd70-sdih)
垢版 |
2022/12/07(水) 13:47:36.67ID:e45EJ0mMd
粘着自体は無視スルーすれば良いからどうでもいいわ
それより将来鯖ログ開示されたとき
誰と誰が自演だったかの答え合わせはしてみたい
0580デフォルトの名無しさん (ワッチョイ ce01-Znoa)
垢版 |
2022/12/07(水) 14:09:36.34ID:O14sy2T20
病的だな
0582デフォルトの名無しさん (アウアウウー Sab5-QZbE)
垢版 |
2022/12/07(水) 15:26:40.34ID:Xzjw4n/la
>>576
> Parl界隈で使ってる言い回しなんだねこのスレで使うなら合ってなかったねで終わる話やろ
それを言ってるならまだ分からないでもないけど 配列 ≠ ハッシュ なんて本人謝ってるのにしつこく絡み続けてる
そんなことでしかマウント取れないんだろうけどマジでなんかの病気だと思うわ
0584デフォルトの名無しさん (ササクッテロラ Sp5f-w5YM)
垢版 |
2022/12/07(水) 15:34:20.23ID:HdWAA0Dip
いいから相手にしない
もう飽きたよ
0587デフォルトの名無しさん (ワッチョイ e75f-UplN)
垢版 |
2022/12/07(水) 19:28:34.64ID:cizNPWpb0
まーだやってるw
0590デフォルトの名無しさん (ワッチョイ 0acf-L4s+)
垢版 |
2022/12/08(木) 08:19:28.46ID:/GcWMRnI0
>>576
そこにPerl界隈でも使ってないとか言う奴が現れて無駄に反論を呼んだ。
0596デフォルトの名無しさん (ワッチョイ 9fc2-He5u)
垢版 |
2022/12/08(木) 13:41:50.14ID:7N/fyoNc0
反応してる時点でおまえ悔しさがにじみ出てるからw
こっちは誰が何と言おうと絶対に揺るがない基礎理論に基づいているから安心してアホにできてオモロイだけ
0601デフォルトの名無しさん (ササクッテロラ Spd7-w5YM)
垢版 |
2022/12/08(木) 18:04:41.79ID:F9H67G14p
今更メモリー管理したくないよぉ
0606デフォルトの名無しさん (ワッチョイ c001-g9pY)
垢版 |
2022/12/08(木) 19:42:03.83ID:pXyaJjcm0
欧米の知的な人たちの間でC++が流行ってるんだろ。
0611デフォルトの名無しさん (ササクッテロラ Sp1b-Xf+d)
垢版 |
2022/12/10(土) 12:26:15.44ID:z6yEzr6lp
C#って、むしろ大規模になって来ると意味不明なエラーが出て破綻しないか?
0612デフォルトの名無しさん (ブーイモ MM8b-CGXW)
垢版 |
2022/12/10(土) 14:59:01.80ID:mMjCV03FM
C#が悪いわけではないけど、メモリー解放とかルーズにしたままある程度コード書けちゃうからね、、、
大規模になってくると無頓着だったメモリー解放が火を吹く感じはある

C++はそんなルーズな書き方してたらすぐ破綻するから、そういうコードは多くないけど初期の実装には多くの時間がかかる感じ
0614はちみつ餃子 ◆8X2XSCHEME (ワッチョイ ff3e-3TNT)
垢版 |
2022/12/10(土) 17:52:23.34ID:brInbnm70
プロジェクトを分割しようとしてもどうにも分離しきれない絡み合った部分ってあると思うんよ。
そういうときは機能別に分割するというだけではなく絡み合った部分は絡み合ったものとしてレイヤとして切り分けると上手くいく。
面倒くさいところは一か所に押し込めて横に切る感じ。

C# のプロジェクトはレイヤで分ける意識が希薄で縦割りばかりするので分離しきれない結合が全体にうっすらと残ってる感じ。
密結合というほどではないけど全体にうっすらなので、面倒くさい箇所が一か所にまとまってるよりしんどい。

というのが私の印象。 C# のことはあんまり知らんけど。
0616デフォルトの名無しさん (ワッチョイ 675f-k8RX)
垢版 |
2022/12/10(土) 20:25:28.70ID:PM5iwksI0
DのUpdateみると1000ms待たないと終わらないように見えるけどそれはいいの?
0617ハノン ◆QZaw55cn4c (US 0H9b-JdnI)
垢版 |
2022/12/10(土) 20:33:03.87ID:6SBPs3AFH
>>614
トップダウン、ボトムアップ、両面から書いていったとき、それが出会うところでグダグダなその場しのぎのコードに書かざるを得ない経験はありますね
0620デフォルトの名無しさん (アウアウウー Sa6b-k8RX)
垢版 |
2022/12/10(土) 21:19:19.36ID:+Ttg8yU5a
int main() {
const int i = 1;
int*j =const_cast<int*>(&i);
*j=2;
std::cout << &i<<" "<< j<<std::endl;
std::cout<<i <<" "<< *j;
}

https://wandbox.org/permlink/DC1E3ycea3UtdBAI

0x7ffc53e76e1c 0x7ffc53e76e1c
1 2

上のやつちょっといじってみた
アドレスの値同じなのに値違うんだけどなんでなんだろ
0627デフォルトの名無しさん (ワッチョイ df28-GD9R)
垢版 |
2022/12/10(土) 22:38:50.72ID:HtRCvZl/0
まつがえたorz
あるいは真にiの値を見たいのなら
 ...(前半は同じ)...
 auto *p = (volatile int*)&i;
 cout << *p << " " << j << endl;
みたいにするとか?
※ 個人の感想です
0629デフォルトの名無しさん (ワッチョイ 8710-bPD3)
垢版 |
2022/12/10(土) 23:01:50.82ID:lr6mtoK80
既に
std::cout << &i<<" "<< j<<std::endl;
により&iとjが同じ値であることは示されてる

auto *p = (volatile int*)&i;
これでも同じアドレスとして解釈されている(試した)

きっとconst_castに限らずconst領域のアドレスを解釈する時点で
ここのコンパイラは別領域を確保するんだな
0631デフォルトの名無しさん (ワッチョイ df28-GD9R)
垢版 |
2022/12/10(土) 23:07:19.81ID:HtRCvZl/0
>>629
↓の間違いなのでは……
std::cout << &i<<" "<< &j<<std::endl
これが同じ値になるのなら、iとjが別の実体という仮説はむしろ棄却され、
鼻から悪魔が出たか、さもなくば>>625の説明ぐらいしか残らない
0633デフォルトの名無しさん (ワッチョイ df28-GD9R)
垢版 |
2022/12/11(日) 00:20:42.40ID:Pzj62nR+0
>>632
左様かスマンカッタorz

今神のお告げがあったが多分
>iと&iが別実体と解釈されてないとこの処理系の挙動は説明できないよ
というのは
>変数iとcout << の引数としての定数1が別実体と解釈されてないとこの処理系の挙動は説明できないよ
と考えたら>>625と同じ……
0641デフォルトの名無しさん (ワッチョイ 8710-bPD3)
垢版 |
2022/12/12(月) 02:44:59.90ID:m98xyCFn0
挙動を考えるというか思想とか背景を考えるのが面白いんだよ
組み込みじゃconst領域は物理的に変えられない場合があるからって
余計な事考えちゃったけどたしかに>>625だろうなって
0642デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/12(月) 14:55:49.27ID:P0mM9QsZM
vector<string> v; の vを辞書順でソートした場合、string自体はメモリ上に
連続して並ぶが、肝心の文字列バッファは free store 上でバラバラに離れた
位置になるからキャッシュ・ミスし易くなるね。
stroustrup氏はリンクリストがキャッシュミスし易いと言って馬鹿にしていたが、
実際には動的配列(vector)でも大差は無い。
なお、リンクリストでキャッシュミスし易い典型例がソート後の全巡回ループ。
そしてその場合、vectorでもstringのようなメモリ資源ハンドルの場合は
キャッシュミスが免れない。
0643デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/12(月) 15:09:17.26ID:P0mM9QsZM
>>642
[補足]
そもそも、C++はcopyの代わりのmoveによる高速化を自慢しているが、
それが意味を持つのはstringのようにfree storeのメモリをポインタで持っている
ようなクラスである。
このご自慢のmoveが良く効くクラスTのvector<T>をソートした場合、
free storeの本当の中味のアドレスはソートされないまま。
なので、vectorを全巡回する時には、アドレスが飛びとびになり、キャッシュミス
が起き易い。
0646デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/12(月) 15:26:03.32ID:P0mM9QsZM
>>645
[補足]
list<string> v2; の場合、push_back すると、
p1 = new string;
相当の事が実行されるが、p1 の内部の文字列バッファも、string のコンストラクタ
の中で
p2 = new char[N];
のようにして free store から確保される。
確率的には、p1 と p2 は非常に隣接したアドレスになっている可能性が非常に
高い。
その結果として、p1をアクセスした直後にp2にアクセスしてもキャッシュミスは起きない。
その結果、vector<string>とlist<string>のソート後の全巡回でのキャッシュミス回数は、
ほぼ同じ。
0647デフォルトの名無しさん (ワッチョイ 675f-3TNT)
垢版 |
2022/12/12(月) 15:33:08.04ID:b4gQwKir0
>>645 そうだね。悪化するのは少しだけだね。
おや? >>642 ではバラバラに離れてキャッシュミスしやすいと言っていた文字列バッファが
リンクリストの話になると近接するのかい?不思議だねぇ。
0649デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/12(月) 15:37:07.44ID:P0mM9QsZM
>>647
>おや? >>642 ではバラバラに離れてキャッシュミスしやすいと言っていた文字列バッファが
>リンクリストの話になると近接するのかい?不思議だねぇ。
ソートしたときには、stringと対応する文字列バッファは意味論的には
くっついている。だから、「対応している」両者は隣接しているんだ。
0650デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/12(月) 15:39:41.84ID:P0mM9QsZM
>>649
[補足]
vector<string>をソートすると、stringの「箱」が新しく確保されてしまうので、
中身だけがmoveされるので、stringと対応する文字列バッファは「離れ離れになる」
list<string>をソートすると、stringはアドレスは全く変化せず、string同士の
リンクのされ方だけが変化するだけだから、stringと対応する文字列バッファは、
メモリー空間上でのアドレスの隣接を維持する。
0652デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/12(月) 15:49:40.91ID:P0mM9QsZM
>>650
[補足]
vector<string>のソート後の様子:
アドレス
0x0000: st100 ---> buf100 (st100とbuf100のアドレスは離れ離れ)
0x0010: st5 ---> buf5 (st5とbuf5のアドレスは離れ離れ)
st100とst5は隣接する。
ソート時に中身のアドレスだけがmove。

list<string>のソート後の様子:
st100 ---> buf100 (st100とbuf100は隣接したまま)
st5 ---> buf5 (st5とbuf5は隣接したまま)
st100とst5は隣接しない(但し、元のアドレスを維持したまま)。
ソート時には、一切のmoveもcopyも全く発生せず。
0654デフォルトの名無しさん (ワッチョイ e701-3npV)
垢版 |
2022/12/12(月) 22:29:51.34ID:EC98/b6s0
天才ですから
0656デフォルトの名無しさん (ワッチョイ df28-GD9R)
垢版 |
2022/12/12(月) 23:33:02.97ID:OmhP4qQH0
キャッシュミスが起きるとか
キャッシュに収まりきらない要素数のリンクリストを
全要素まんべんなくアクセスし続ける場合とかの話であって
そうなれば区々たるデータ構造などあんま意味を成さなさげ
0661デフォルトの名無しさん (ワッチョイ dfad-KKgq)
垢版 |
2022/12/13(火) 09:37:04.67ID:XemHbbXi0
ありていにいえば、他のレイヤーのデータを参照する時にハッシュを使わないと処理速度が落ちてしまうので、いたるところに速度対策でハッシュ参照が実装されているってのがFA
0673デフォルトの名無しさん (ワッチョイ a7e4-5DNi)
垢版 |
2022/12/13(火) 16:50:01.90ID:nLXwCo+B0
>>669
c++のunorderd_は挿入時に挿入要素のキーによるソートが行われず要素の格納順が実装依存なコレクションに付けられている名称だから、vectorがunoreded_かどうかと言えばyesじゃない?
0690デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/13(火) 19:24:14.15ID:jWNvO27sM
そもそも、ordered かどうかは定義の問題。
まず、mapは、(key,value)を持っていて、keyで検索できる。setは、keyだけでvalueが無いが、
keyで検索できる。setは、mapでvalueをkeyにしたようなもの。だから、以下ではmapだけ
の話をする。
mapやunorderd_mapは、「検索」機能とbegin(),end() を利用した「巡回機能」の
両方を持っていて、巡回を key の大小関係順に巡れるかどうかで、
ordered かどうかが決まる。
バランス木(赤黒木など)を使う方が 接頭辞なしの map、ハッシュ法を使う方が
unorderd_map
前者の場合は、常に自動的に並び替えられた状態で格納される。
一方、そもそも vector は、好きな順序で入れられて決まったキーもなければ
自動的に並び替える機能も持ってないし、orderedかどうかを定義しても
特に意味が無い。そもそも、orderdのvectorが存在し無い。
また、故意に作ってもしょうがない。
0694デフォルトの名無しさん (ワッチョイ 675f-k8RX)
垢版 |
2022/12/13(火) 19:28:56.13ID:sAeHrnUZ0
巡回機能って何
0695デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/13(火) 19:37:41.71ID:jWNvO27sM
>>694
まだ使ったことが無いので書き方が間違ってるかも知れないが、
map<T,V> m;
に対して、
for ( auto &r : m ) {
 cout << r.first << ":" << r.second << "\n";
}
で巡ることができる機能の事を言ったつもり。
for ( auto i = m.begin(); i != m.end(); ++i ) {
 cout << m[i].first << ":" << m[i].second << "\n";
}
と等価だと思う。
ただし、一度も使ったことが無い。
0697デフォルトの名無しさん (ワッチョイ e701-3npV)
垢版 |
2022/12/13(火) 21:45:11.86ID:FUi24cxt0
keyとしてpointerを指定したmapがpointeeで正しくソートできるように
3番目のテンプレート引数にpointerを剥がして比較するless演算子を
以下のように渡します
g++ではm1は-std=c++17では不可ですが-std=c++20だと通ります
m1にはcomparatorの型しか情報を渡しておらず
m1は実装に関しては何も知らないはずなのですが
正しくpointeeでソートします なぜ?

#include <iostream>
#include <memory>
#include <map>
using namespace std;
int main ()
{
using Ptr = shared_ptr <int>;
auto comparator ([] (const Ptr &lhs, const Ptr &rhs) {return *lhs < *rhs;});
using Map = map <Ptr, int, decltype (comparator)>;
// Map m0 (comparator); // -std=c++17と-std=c++20で可
Map m1; // -std=c++17で不可, -std=c++20で可
m1.insert (make_pair (make_shared <int> (2), 2));
m1.insert (make_pair (make_shared <int> (1), 1));
m1.insert (make_pair (make_shared <int> (3), 3));
for (const Map::value_type &key_value: m1)
cout << key_value.first << ' ' << key_value.second << '\n';
return 0;
}
0700デフォルトの名無しさん (ワッチョイ e701-3npV)
垢版 |
2022/12/13(火) 22:27:14.40ID:FUi24cxt0
納得しちゃダメだった
ラムダ式の型は実装ごとに異なるみたいですね
以下__cxa_demangleがg++依存だけども
#include <iostream>
#include <memory>
using namespace std;
namespace abi {
extern "C" {char *__cxa_demangle (const char* __mangled_name, char* __output_buffer, size_t* __length, int* __status);}
}
string name_of (const type_info &p)
{
int status (0);
char *tmp (abi::__cxa_demangle (p.name (), 0, 0, &status));
string result (tmp);
free (tmp);
return result;
}
int main ()
{
using Ptr = shared_ptr <int>;
auto c0 ([] (const Ptr &lhs, const Ptr &rhs) {return *lhs < *rhs;});
auto c1 ([] (const Ptr &lhs, const Ptr &rhs) {return *lhs > *rhs;});
cout << (typeid (c0) == typeid (c1)) << '\n';
cout << name_of (typeid (c0)) << '\n'
<< name_of (typeid (c1)) << '\n';
return 0;
}
$ g++ -std=c++20 test.cpp
$ ./a.out
0
main::{lambda(std::shared_ptr<int> const&, std::shared_ptr<int> const&)#1}
main::{lambda(std::shared_ptr<int> const&, std::shared_ptr<int> const&)#2}
0701デフォルトの名無しさん (ワッチョイ 675f-3TNT)
垢版 |
2022/12/13(火) 23:32:00.27ID:vjOTFb3s0
>>697
> m1にはcomparatorの型しか情報を渡しておらず
> m1は実装に関しては何も知らないはずなのですが
ここが思い込みかと。
ラムダ式のクラス型に比較関数が含まれてて、その内容もインスタンスに依存しないし、
比較方法は十分伝わってるから問題ないということで何も不思議じゃないと思う。
0702デフォルトの名無しさん (ワッチョイ e701-3npV)
垢版 |
2022/12/13(火) 23:43:34.19ID:FUi24cxt0
>>701
はい
ラムダ式の型というものを理解していませんでした
型で実装を伝えることができるのは
関数ポインタと大きく異なっていて面白い性質ですね
0704デフォルトの名無しさん (テテンテンテン MM8f-0RkQ)
垢版 |
2022/12/14(水) 08:35:41.62ID:YVPbaJHSM
>>687
c++のunorderd_/(ordered_)は要素をキーにしてコレクションがソート済みになるかどうかを意味してると考えれば

全然違うよ。標準くらい読みなよ。

Associative containersとUnordered associative containerの本質的な違いはキーの定義。
Associative containersのキーは順序で比較可能でなくてはならず、Unordered associative containerは同値で判定可能でなくてはならない。
ついでに言うと、配列は(記憶に間違いなければ)直接メモリ番地で指定できなきゃならなくて、キー(みたいなもの)も(正)整数でなくてはならなかったはず。
0711デフォルトの名無しさん (ワッチョイ 479c-0RkQ)
垢版 |
2022/12/14(水) 11:33:30.37ID:ZSc/wamY0
>>709
>同値「かどうか」判定可能じゃないの?

意味不明。

厳密に言うなら、Unordered associative containerが要求しているのはa == b a != b。
同値「かどうか」とか曖昧な突っ込みで何やりたいの?
0712デフォルトの名無しさん (ワッチョイ a7e4-5DNi)
垢版 |
2022/12/14(水) 12:05:38.08ID:apgWSyiy0
>>704
なるほどだいたい理解した
つまり最初の話に戻るなら unordered_multivector というものを考えた場合、格納する要素を a == b と a != b が定義されているものに限定して、
最悪の実装を考えると要素の格納方法は vector そのもので良くて要素のサーチは先頭からリニアに a == b をチェックしていくことになり、
unordered_vector ならば要素格納時に a == b なものを除外すればよいというわけだね
0716デフォルトの名無しさん (テテンテンテン MM8f-0RkQ)
垢版 |
2022/12/14(水) 12:39:11.82ID:14xvhmEyM
>>712
>>705

中身とキー(みたいなもの。インデックス・添字)は別物。

あと、標準だと
The elements of a
vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other
than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
だから、vector にunorderとかmultiとか考えても意味がない。混乱の元だからやめたほうがいい。
0722デフォルトの名無しさん (アウアウクー MM1b-PRdN)
垢版 |
2022/12/14(水) 17:18:36.72ID:qZt9MbKWM
>>711
いや「同値で判定可能」って日本語として意味通ってないじゃん
取れる揚げ足を作った奴が悪いよ
「厳密に言うなら〜が要求しているのは a==b a!=b」も全然厳密じゃないじゃん
a, b が何なのかも書いてないし、operator== と operator!= が定義さえされてればいいのか (a==b) ^ (a|=b) が true である必要まであるのかもその書き方だと分からない
0725デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/14(水) 17:58:56.90ID:ekFaWlb/M
>>697
>m1は実装に関しては何も知らないはずなのですが
>正しくpointeeでソートします なぜ?
結論から言うと、ラムダ式は 関数呼び出し演算子 operator()() を
持った名前なし functor に対応していて、「デフォルト値」で構築
しても機能を果たすから。

[詳細]

ラムダ式は、名前なし functor で、関数呼び出し演算子 operator()() を持った
クラスに対応している。いまの場合、
auto comparator ([] (const Ptr &lhs, const Ptr &rhs) {return *lhs < *rhs;});
は、
class SomeFunctor {
public:
 bool operator()(const Ptr &lhs, const Ptr &rhs) {return *lhs < *rhs;}
};
に対応していて、
SomeFunctor cmp{};
で SomeFunctor のオブジェクトを作ってから、
bool b = cmp(lhs, rhs);
とすると比較できる。
故に map クラスは SomeFunctor のオブジェクトをデフォルト値で
初期化すればいいことになるから、ユーザーが SomeFunctor の初期値
を渡さなくて良い。
実際に、mapクラスは、デフォルト値で初期化した SomeFunctor のオブジェクトを
基本クラスのメンバ変数に(実質的に)持っている。
0727デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/14(水) 18:13:49.08ID:ekFaWlb/M
>>704
いや、ordered_が付かないmapやsetは、順序で並び替えることも定義の一部になっていて、
範囲forで巡ると、挿入した順序ではなく、比較関数で比較した結果に基いてソートされた順序になる。


https://stackoverflow.com/questions/7648756/is-the-order-of-iterating-through-stdmap-known-and-guaranteed-by-the-standard

Yes, that's guaranteed. Moreover, *begin() gives you the smallest

C++
・std::map is a sorted associative container

https://stackoverflow.com/questions/11274978/are-c-stdmapstring-string-ordered


are STL maps ordered?

Yes, a std::map<K,V> is ordered based on the key, K, using std::less<K> to compare objects, by default.
So if I iterate over it, it will iterate with the first insert string first?
No. It will iterate based on the sorted order, not the order that you inserted elements. In the case of std::string, it sorts in lexicographic order (alphabetic order).
If you want to iterate based on the insertion order, you're better off using a sequence container, such as a std::vector or a std::list.
0730デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/14(水) 18:20:54.42ID:ekFaWlb/M
>>702, 703
そういうことやね。
ラムダ式は、関数呼び出し演算子 operator()()を持ったクラスに対応していて、
その演算子が、ラムダ式の中身になっているから、テンプレート引数に
クラスの型を渡すだけで関数を渡せる。
ローカル変数をキャプチャしている場合は、どうなっているか良く知らないけども、
0734デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/14(水) 18:36:10.47ID:ekFaWlb/M
>>733
俺は、紙に書いてあるのを丸覚えてるわけじゃなくて、あたまのなかで
1秒でシミュレーションして自分で割り出してるが、簡単すぎるので、
テキトーに書いてしまう癖が有って、打ち間違える。
0735デフォルトの名無しさん (スプッッ Sd7f-GCrc)
垢版 |
2022/12/14(水) 18:38:06.37ID:boxWAqPPd
int x,y;
auto f = [&x,y](){};
のとき、

fの型は
struct{
int& _x;
int _y;
void operator()();
};

相当だとは思う。
コンストラクタ周りがどういう扱いされてるかはわからん
0740デフォルトの名無しさん (テテンテンテン MM8f-0RkQ)
垢版 |
2022/12/14(水) 19:04:38.48ID:YVPbaJHSM
>>727
key とelementが紛らわしいなぁ。
c++標準は「keyで並び替える」。setはkeyがelementになるので結果として「elementで並び替えたのと一緒」となるだけ。key とelement をしっかり区別しないと擬似問題になるよ。
0745デフォルトの名無しさん (スップ Sd7f-exKU)
垢版 |
2022/12/14(水) 19:33:54.85ID:Y6rgBuPWd
配列の中身をmultisetのkey,element
配列のインデックスをmultisetの要素のn番目のn
ととらえれば配列はmultiでunordered

配列の中身をelement
配列のインデックスをkey
ととらえれば配列はuniqueでordered

実際はどちらでもない
0750デフォルトの名無しさん (ワッチョイ e701-3npV)
垢版 |
2022/12/14(水) 21:17:02.90ID:x1JxbarV0
>>725,730
有難うございます
その理解に至りました
それと>>698の合わせ技で
mapのkeyにポインタを入れるのが随分とスマートになった印象です

using Ptr = shared_ptr <int>;
auto comparator ([] (const Ptr &lhs, const Ptr &rhs) {return *lhs < *rhs;});
using Map = map <Ptr, int, decltype (comparator)>;
Map m1;
0751デフォルトの名無しさん (アウアウウー Sa6b-2vTk)
垢版 |
2022/12/14(水) 21:22:32.15ID:XhtdH9iqa
>>691-692
知ってた
0754デフォルトの名無しさん (ワッチョイ bf8c-eoOe)
垢版 |
2022/12/14(水) 22:58:57.25ID:6VpEeBw/0
>>747 >>748
multimapの"multi"の意味と違うなぁ。それはmapでもできる話じゃない?
cpprefjpに解説あるから調べたら?

C++ Standards だと22.2.6.4ですな。
(N4849)
An associative container supports unique keys if it may contain at most one element for each key.
Otherwise, it supports equivalent keys.
The set and map classes support unique keys; the multiset and multimap classes support equivalent keys.
0757デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/14(水) 23:35:44.65ID:K5HiKCY5M
>>756
なぜそう思うかって言うと、俺が言ったことがちゃんと通じる相手も存在しているからだよ。
客観的にハイレベルだと思える人には俺の言ったことが通じる。
しかも、この話だと確実に通じると思ったことはちゃんと確実に通じる。
ところが、この板だと結果は惨敗。全く通じなくて、逆にけなされ、馬鹿にされる。
0767デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/15(木) 00:26:32.79ID:3Zw/afEhM
>>766
なお、東大生でも理解力が無い人は理解力無いと思う。
本当に頭のいいのは、一部の学科に集中している。
東大以外でもレベルの高い大学なら理解できる人多いぞ。
ここにも東大生は来てるかも知れんが、残念ながら頭がいいタイプの人は来てない。
0771デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/15(木) 00:48:44.56ID:3Zw/afEhM
ホリエモンや高橋洋一も言っていたが、レベルが合わないと話してることが
全く理解されなくて、むしろ馬鹿にされ、阻害されるものなんだぞ。
高橋洋一にいたっては東大に行っても理解されなかったそうだ。
根本的に頭がいい人はそうなる。
日本では特にそういう人を社会から除外するし。
0773デフォルトの名無しさん (オイコラミネオ MM7b-VZV0)
垢版 |
2022/12/15(木) 00:56:26.15ID:3Zw/afEhM
>>772
このスレでは、目に余るものがあって、
そもそも、学級崩壊しているような状態で、まともに議論できない。
正しいことを言ってる人を馬鹿にして、間違ってる子と言ってる人が大きな
顔をして、自分が正しいことを言っているかのような態度をとる。
そもそも議論の土台が出来て無い。
まずは、ホームルームや道徳の様なことから始めなくては。
0774デフォルトの名無しさん (ワッチョイ e701-3npV)
垢版 |
2022/12/15(木) 01:09:34.07ID:5pPRyT0s0
コミュニケーションってのはコンパイラと違って
言語モデルやその背後にある思考モデルはダイナミックに変化する
それについていけなければ会話は成立しない
更に特定の一つコンパイラを相手にしていれば良いという訳でもない
0776デフォルトの名無しさん (ワッチョイ e701-3npV)
垢版 |
2022/12/15(木) 01:24:05.73ID:5pPRyT0s0
会話ってのは一人でやるもんじゃないんだよ
双方が相手の頭の中を推定できたときに初めて噛み合う
相手に自分の頭の中を推定しやすいような
手掛かりを上手に出すのも技術のうち
0778デフォルトの名無しさん (ワッチョイ bf8c-eoOe)
垢版 |
2022/12/15(木) 01:58:19.99ID:yiRddat50
>>762
>745を見直したけど意味不明だわ。
これは>719
>vectorのキーはuniqueでordered
>vectorの中身はmultiでunordered
>考えるまでもなく自明
の説明ということだよな?

> 配列の中身をmultisetのkey,element
> 配列のインデックスをmultisetの要素のn番目のn
> ととらえれば配列はmultiでunordered
で配列をpair<K,T>[]に限定するような話が突然出てくる。
>712のunordered_vectorに頭の中身が引きずられてない?
そんなにunordered_vectorの話がしたいの? 俺は嫌だよ。

>配列の中身をelement
>配列のインデックスをkey
>ととらえれば配列はuniqueでordered
はかすかに議論の流れに沿っているけど、
>実際はどちらでもない
で放り投げられているから、結論として何を主張したいのかも分からん。
これじゃ「>719はどちらも間違い」という主張にしか見えん。
>745にマトモな結論も主張も無いから、この話がどう>747 >748 につながるかも分からん。

エスパーじゃないんだから、バラバラで繋がりの無い情報を読んでも>762の頭の中なんて分からんよ。
「だとしたらアホだ 」と言う前に、引用レスぐらいちゃんと読み直して補足情報ぐらい書いたら?
0779デフォルトの名無しさん (ワッチョイ bf8c-eoOe)
垢版 |
2022/12/15(木) 02:20:47.08ID:yiRddat50
>>775
そりゃ、有り難くも相手が理解しようと努力してくれているからだろ。

会話で「情報の非対称性」は意識している?
相手がどのような情報を持っているのかを無視して、自分の立場を
ゴリ押しして相手にマウントしようとすれば、そりゃ相手に嫌われるわ。
まあ、相手に嫌われるのが目的ならそれでOKだけど。
0782デフォルトの名無しさん (スッップ Sdff-c2mE)
垢版 |
2022/12/15(木) 07:27:41.09ID:dbf8SNdVd
でかい声出しても人を小馬鹿にしても
それでハッシュでないものがハッシュになるわけでなし
無駄で関係ない努力をし、そのために他人に迷惑が及んでも
構わないという自己中心的なやつ
0787デフォルトの名無しさん (テテンテンテン MM8f-0RkQ)
垢版 |
2022/12/15(木) 12:47:10.10ID:WaHslr7gM
hashのレスはあんまり読んでいないんだけど、c++標準のhashの話だよね?

c++標準と関係の無いhashをc++スレで持ち出してhash hash 言っているわけじゃないよね?

まさかそんなアホいないよね?
0791デフォルトの名無しさん (ワッチョイ a701-u86g)
垢版 |
2022/12/15(木) 19:54:56.58ID:SaYQ/lLy0
Perl民は70代中心だからな。
0793デフォルトの名無しさん (ワッチョイ dfad-KKgq)
垢版 |
2022/12/16(金) 08:43:50.12ID:Sk8Nrr7L0
名前、それ自体がハッシュだよ
ありとあらゆるものが名前を与えられることによって唯一性・独自性を確保する
つまり、人間の脳は万物をハッシュで管理している
0801デフォルトの名無しさん (ワッチョイ 675f-k8RX)
垢版 |
2022/12/16(金) 12:26:19.15ID:YwJTJAAR0
<=>初めて知ったけどめちゃ便利だな
うちの環境じゃ使えないのが残念だけど
0802デフォルトの名無しさん (スプッッ Sd7f-GCrc)
垢版 |
2022/12/16(金) 15:18:01.45ID:h3Zax2und
operator==のdefaultは便利だわ
0803デフォルトの名無しさん (アウアウエー Sae2-oWW1)
垢版 |
2022/12/17(土) 02:36:30.45ID:ufrS8am+a
a > b, a < b, a == b を一度に判定するだけの演算子の何がそんな便利やねん!
とおもったらこれ一つ定義するだけで各種比較演算子全部児童生成してくれるのね
なるほどこりゃ便利かも
0816デフォルトの名無しさん (ササクッテロロ Spb3-7wYa)
垢版 |
2022/12/20(火) 15:17:57.65ID:/qMRbodsp
自称だけどな
0820はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/25(日) 20:29:17.71ID:8blj/qJt0
>>818
原則としては std 名前空間になんらかの宣言や定義を追加したら未定義ということになってる。
https://timsong-cpp.github.io/cppwp/n4861/namespace.std
その事例も該当すると思う。

条件付きで許されている特殊化はあるが C++20 から制限が強化された。
(従来は条件付きで「テンプレートの特殊化を追加できる」だったのが「クラステンプレートの特殊化を追加できる」に改められている。)
ユーザー定義型ごとのカスタマイズを許したい場面では Customization Point Object (CPO) を
活用する方向性なので特殊化でどうにかする必要もないし制限が強くなることはあっても緩和されることはないんじゃないかな。
0826デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/25(日) 23:15:00.75ID:8rnFU1jp0
>>825
いやまぁ>>818は俺じゃないので俺も必要性を感じているわけではないけども
具体的に何を恐れているのか分からん
0828デフォルトの名無しさん (ワッチョイ 8d01-s0Sd)
垢版 |
2022/12/26(月) 01:18:22.88ID:D/1vl6x80
>>827
ワクワクしてこないか?
0829デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 01:20:46.52ID:YnLWxzzl0
>>827
oresamaライブラリの中でoresama名前空間があって
arrayが定義されていたとして
oresamaライブラリとは別のプロジェクトで
oresama::array前方宣言したときに
起こりうることは予想がつくよね?
それがstd名前空間だと動作が未定義だとのことだけども
何が違うのか分かります?
0832はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/26(月) 02:20:44.42ID:OBkbHJZM0
>>831
コンパイラの内部に興味を持って調べたいならどんどんやればいいよ。
詳しい人が増えるならそれはたいへん喜ばしい!

でも、リッチな C++ コンパイラのソースコードを読んで様々な最適化がどう組み合わさるかまで把握するのは
相当に高い技能を持った達人でないと無理なのでこのスレ程度ではなんもわからんと思う。
世の中にはこれを保守している人がいるんだからありがたい話だよな。

私がどこかで見たおぼろげな記憶では標準テンプレート関連の一部で
マングルのルールが異なる (名前が短くなるようにしてる?) というのがあるので
変なことをすると破綻することもあるのかもしれない。
0836デフォルトの名無しさん (ワッチョイ ebda-w5mw)
垢版 |
2022/12/26(月) 07:41:41.79ID:zTKHQ8850
clangのソースコードはC++プログラムの書き方の勉強になりますね
0837デフォルトの名無しさん (スプッッ Sddb-lg2t)
垢版 |
2022/12/26(月) 08:06:50.83ID:FVIubv9sd
std::arrayってなんらかのusingであることが(コンパイラ側への制限として)許されてたりするんか?

もしarrayの実体がこんな実装だったら
namespase std::__internal {
template<class T, size_t>class array{...};
}
namespase std:: {
template<class T, size_t>using array=__internal<T,size>;
}

勝手にこれ書いたらまずくならんか?
namespase std{
template<class T, size_t>class array;
}
0839デフォルトの名無しさん (ワッチョイ 8f7c-PRRE)
垢版 |
2022/12/26(月) 11:35:27.15ID:v25C8vnQ0
>>818
それやると特定のC++バージョン、特定のコンパイラでしか
コンパイルできないコードになりかねないし、
普通に #include <array> すればいいだろ。

それともそれが出来ない理由があるとか?
0840デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 12:12:38.12ID:YnLWxzzl0
>>832
なるほどマングリング変えられるとリンカーエラーで
しばし悩むかもしれませんね

>>837
これはコンパイルで弾かれるので分かると思います

おふた方とも勉強になりました! 有り難うございます
しかし未定義動作ってほど酷いことにはならないのかなぁと思います
なめてますかね私?
0841デフォルトの名無しさん (アウアウウー Sa1f-SvsN)
垢版 |
2022/12/26(月) 13:31:39.98ID:6bMfB0bxa
>未定義動作ってほど酷いこと

は?
0843デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 13:49:22.29ID:YnLWxzzl0
>>841
未定義動作とはコンパイルもリンクも通って実行できるけど
どんな動作をするか分からない(未定義)ので
事前に分かるコンパイルエラーやリンカーエラーに比べて
「酷い」と表現しました
いわゆる「鼻から悪魔」
0845はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/26(月) 14:17:52.01ID:OBkbHJZM0
もしも「必ずエラーとして報告されるべき」みたいな仕様にしたら std の特別扱いが要るから
標準ヘッダのファイルに素朴に書くだけな実装はやりにくくなるし……。
0846デフォルトの名無しさん (ワッチョイ 2b01-s0Sd)
垢版 |
2022/12/26(月) 14:22:21.57ID:uyDYkqVs0
void InitBoard(void) // 盤を初期化
{
int x, y;

for (y = 0; y < YMAX; y++)
{
for (x = 0; x < XMAX; x++)
{
board[x][y] = 0;
}
for (x = 0; x < XMAX; x++)
{
num[x] = 0;
}
}
}

この処理の無駄を省くコードおしえてください
0852デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 14:49:02.84ID:YnLWxzzl0
>>847
>>821からの流れは
実際に「酷い」鼻から悪魔が出る処理系はないんじゃないかな?って問い掛けです
少なくともここのスレではコンパイルエラーやリンカーエラーになる事例は
指摘がありましたが「酷い」ことになる事例は出ていません(誰かもしあれば?)

なぜそう考えるかは名前空間oresamaでは合法で
名前空間stdのみに規格において例外的な規定がなされているからって程度です
>>845のようにエラーが明示的に出ないのも
酷いことにならんのじゃないかなぁと
私が考えてしまうことに貢献しているかも
0853はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/26(月) 14:50:30.84ID:OBkbHJZM0
>>846
std::fill を使うのが妥当じゃないかな?

memset でも普通は問題は起きないと思うけど
メモリブロック (バイト列) に対する操作だから board の型によっては
問題が起こることはなくもない。
0854デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 14:51:24.85ID:YnLWxzzl0
>>851
そういうことではない

文法的にダブルスタンダードになってるのが気持ち悪い
名前空間stdもoresamaも同じ取り扱いである方が
文法的に美しいって感じているから
実際には最適化のためにstdは特別扱いが規定されている
0856デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 15:10:52.71ID:YnLWxzzl0
>>855
煽ってものらないよw 誰もそんなことは書いていない

酷いことになる事例を教えてねってことを書いています
どういうこと(最適化?)を想定してダブルスタンダードにしたのか
動機を知りたくないですか?
0858はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/26(月) 15:26:40.53ID:OBkbHJZM0
>>854
自分が作ったライブラリの名前空間に何を追加されても正しく動く (または必ずエラーになる) ように保証してんのか?
各ライブラリごとの挙動に保証していることと保証してないことがあるのは当たり前のことだろ。
お前のライブラリについての保証はお前がするから「言語では」関知しないってだけで、
oresama に何を追加してもよいことが保証されてるわけではない。
0859デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 16:14:39.95ID:YnLWxzzl0
>>858
たぶん伝わってないな
以下をユーザが自分のソースに書くのは>>820の言うように規格で禁じられている
namespace std {
template <class T, std::size_t N>
struct array;
}
同じくoresama::ARRAYなるカスタムのクラステンプレートが定義されていたとして
以下をユーザがソースに書くのは合法
namespace oresama {
template <class T, std::size_t N>
struct ARRAY;
}
これをダブルスタンダードで気持ちが悪いと思っている
最適化との説だけども
具体的なことを知っている人がいたら聞きたいな
0860デフォルトの名無しさん (ワッチョイ 5328-gB2L)
垢版 |
2022/12/26(月) 16:17:49.67ID:+99B24rl0
>>846
そのboard[x[][y]はゼロフィルしても良い配列?
盤外に飛び出す桂馬飛びの高速判定テクニックとして実はboard[-1][-2]が壁のコードになっている
とかありそう
※ 全くの想像です
※ 未定義動作と言われても知らそんこの場合アセンブリコードが正しくて速ければええんじゃ
※ この場合2次元配列はやめてカラム数が2のべきの1次元配列であるべき
※ ここまで全くの妄想です
0868はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/26(月) 16:55:21.28ID:OBkbHJZM0
>>865
すでに >>837 で示されてる。 見かけ上の名前は別名であるかもしれない。
別名ではない実装で書かれていることがはっきりしていて将来も変更されないと oresama::ARRAY について
保証されているならそれをあてにしてもいいんじゃないの。
で、それを保証するかどうかはライブラリを作ったやつの裁量次第。
0870デフォルトの名無しさん (ワッチョイ 5328-gB2L)
垢版 |
2022/12/26(月) 17:11:08.06ID:+99B24rl0
namespaceはシンボルの衝突を防ぐためのしくみなのに
後から要素を追加できる仕様の方がおかしいfinalizeできるべき

だいたいnamespace oresama にX=サンが "bar.h" にて void oresama:foo()を定義して、
C++の標準ライブラリ仕様しか見ていないY=サンが "baz.h" にて同じシグネチャで異なる実装の
void oresama:foo() が実装されてしまう危険性が避けられない
のだから第三者によるnamespace内への後付けは本来言われるまでも無く禁止されるべき事項、

同一シグネチャで異なる実装があったらリンク時にエラーになる、と気体することは場合に掘っては全くできない
http://0xcc.net/blog/archives/000060.html

ちなVS2010だともっと簡単に(スタティックリンクでも)起こせるorz
0871デフォルトの名無しさん (ワッチョイ 5328-gB2L)
垢版 |
2022/12/26(月) 17:13:25.25ID:+99B24rl0
訂正orz
誤1: C++の標準ライブラリ仕様しか見ていないY=サン
正1: oresamaのオリジナルの仕様書しか見ていないY=サン

誤2: 場合に掘っては全く
正2: 場合によっては全く
0873はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/26(月) 17:58:37.42ID:OBkbHJZM0
>>872
前方宣言自体はいいよ。
そのライブラリ内でどう定義されているかわかっていて**妥当な前方宣言を出来るなら**。
将来のライブラリの更新があっても妥当でありつづける (または妥当でなくなったときに追従する) なら。

いちいちライブラリが保証していない内部仕様を調査して妥当かどうか確かめなきゃならない、どんな干渉が起きるかわからない
ってのは (ライブラリの仕様としては) 未定義じゃろ。
0875デフォルトの名無しさん (ワッチョイ 1301-iijX)
垢版 |
2022/12/26(月) 18:40:09.55ID:+xP92Jxa0
>>846
C言語はboard[x][y]のy側が連続に配置されるから for(x = ...){ for(y = ...){ ... } } の順にネストした方が効率的になる可能性が高いので俺なら
for (x = 0; x < XMAX; x++){
for (y = 0; y < YMAX; y++){
board[x][y] = 0;
}
num[x] = 0;
}
って書くと思う
0880デフォルトの名無しさん (ワッチョイ f176-lg2t)
垢版 |
2022/12/26(月) 21:47:21.55ID:6ywYYiev0
未定義動作は未定義だよ

意図通り動いても、
デバッグするのに便利な例外が投げられても、
まともに動いてるように見えてメモリ壊してても、
コンパイルエラーになっても問題ない

コンパイラと実行環境は求められる動作が決まってないから
0882デフォルトの名無しさん (ワッチョイ a1c2-dmhP)
垢版 |
2022/12/26(月) 23:28:38.90ID:8d7AMOhX0
>>877
できることとやっていいことは違うということを区別してるかとあんたに聞いているんだ
そこに他人の発言を持ち出す余地はない

答えに窮しているんなら駄レスしねえで黙ってろ
0884デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/26(月) 23:57:12.44ID:YnLWxzzl0
>>882
>>859に書いてあるから読みたまえ
0885デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 00:01:58.89ID:QO3hLMTW0
>>820
思ったんだけどさ前方宣言は`declarations'に入ってないってことはないかな?
以下が原文なんだけども
>Unless otherwise specified, the behavior of a C++ program is undefined
>if it adds declarations or definitions to namespace std or to a
>namespace within namespace std.
文からは入ってるとも入ってないとも俺には判断がつかない
確かな見解がある人はいるかな?
0888デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 00:14:08.27ID:QO3hLMTW0
>>886
>>859は俺の投稿だよw
0890デフォルトの名無しさん (ワッチョイ a1c2-dmhP)
垢版 |
2022/12/27(火) 00:18:30.98ID:9ztV+U0x0
ヘッダファイルそのものを改造することだってできる
ISO/IEC14882のヘッダファイルだけ改造しちゃいけなくて
それ以外のヘッダファイルは改造していいことにしたいのかよ
ダブスタだからって? バカか
0892デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 00:21:11.64ID:QO3hLMTW0
>>887
>>865以降も読んでくれ給え
前方宣言で鼻から悪魔が出るケースは名前空間std以外ではない
コンパイルエラーやリンカーエラーで弾ける

名前空間stdでもないと思い始めている
規格の`declarations'は普通の宣言のことで
前方宣言はこれに入らない説に傾いてきた
0893デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 00:22:43.58ID:QO3hLMTW0
>>889
3行目に書いてあるから読みなよ
0898デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 00:36:22.67ID:QO3hLMTW0
>>896
俺は優しいからね

>>859
>以下をユーザが自分のソースに書くのは>>820の言うように規格で禁じられている
>namespace std {
> template <class T, std::size_t N>
> struct array;
>}
規格で禁じられていると書いている人間が
「できることとやっていいことは違うということを区別して」いないわけなかろう
0906デフォルトの名無しさん (ワッチョイ 5328-gB2L)
垢版 |
2022/12/27(火) 00:50:13.48ID:R1/11RYB0
「勝手に」が抜けてたorz
X=サンが*勝手*に追加した "bar.h" にて void oresama:foo()を定義のを知らずに
Y=サンが "baz.h" にて同じシグネチャで異なる実装の void oresama:foo() が実装されてしまう
と言う場合は覿面に意図しない動きになる(ことがある
0918デフォルトの名無しさん (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 01:14:43.51ID:QO3hLMTW0
>>916
おまいさんは威勢よく俺を煽ってたけども
規格も読んでなかったということだ
根拠としたのは恐らく>>820の書き込みのみ
俺は純真なので痛く傷ついたんだよ
他人の言説を無批判に信じて自らは確かめることなく
人を攻撃することはやめてくれ
0919はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/27(火) 01:34:54.20ID:G9AKlNLO0
前方宣言が宣言でない可能性なんて考えたこともなかったが
たとえば単にポインタと書いてあるときにメンバ関数ポインタを含んでなかったりすることを
思い出せば変な用語になってる可能性は考慮にいれるという姿勢は必要かもしれない。

あらためて検討してみたところ、前方宣言という用語の直接的な定義はないが仕様中で
前方宣言 (forward declaration) と呼ばれているものは宣言に該当するし、
単に宣言の位置が前方である宣言のことを前方宣言と呼んでいると解しても良いと思う。
0921デフォルトの名無しさん (ワッチョイ 6d5f-aH43)
垢版 |
2022/12/27(火) 02:48:53.38ID:fnhKiHjQ0
>>892
>865の質問は>866,868で答えが出てて、その前の話に影響無いし・・・と読み進めると
>872で「前方宣言は規格で合法」とかいう当たり前に見える意味不明な話につづいており・・・

どうも>859以降の「合法」が↓のようなよくある解釈とは違うようであることに気付いた。
https://cpprefjp.github.io/implementation-compliance.html
> 合法 (legal)・違法 (illegal): これらの語はプログラムに対しても慣用されるが、具体的な意味は明確でない。 プログラムの正しさには複数の水準があるためである。 適格、またはすべての規則を満たす、または未定義の動作を含まないなどが考えられる。
明確な言葉で言い換えられるまで下手に考えても不毛そう。

「前方宣言は」というのも「ユーザー側コードに~な前方宣言を加えて利用していた場合にライブラリ更新があっても~」
とかいう意味になりそうだけど端折りすぎて意味不明になってる。

「鼻から悪魔」は未定義動作と同じ意味のつもりで使ってそうだけどコンパイルエラーやリンクエラーは除くようでもあり
これも未定義動作とは違う何か。

さっきキレちらかしてた人もこんな感じで我慢できなくなったんだろう。
明確な用語を使うように気を付けて主張を整理しないと、君とまともに会話してくれる人居なくなると思うよ。
0942天災 ◆41t0I.PYBW0z (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 12:29:08.28ID:QO3hLMTW0
前方宣言が確かに>>820の`declarations'に含まれる根拠があれば示して下さい
前方宣言で鼻から悪魔が出ることは
懸案事項の名前空間stdの場合は保留として他にないと思う
>>837はコンパイルエラーで弾かれるので鼻から悪魔は出ない
あれば教えて下さい
0949デフォルトの名無しさん (スップ Sd03-4fWv)
垢版 |
2022/12/27(火) 13:22:50.11ID:WVVp8u06d
現実的な話としては、未定義動作静的解析で見つけ出してillーformed扱いしてコンパイル拒否するコンパイラがあったとして、それは規格違反ではない
当たり前だろ、だって未定義なんだから
0953天災 ◆41t0I.PYBW0z (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 13:35:30.55ID:QO3hLMTW0
>>951
初めて聞いたよ
0955デフォルトの名無しさん (スップ Sd03-4fWv)
垢版 |
2022/12/27(火) 13:43:49.52ID:WVVp8u06d
>>954
何が問題なの?何だろうと問題にしないのが未定義という事だぞ
それ以上言うなら「未定義といえどもコンパイルとリンクは必ず通らなければならない」って規格書に書いてある場所提示してね
0960デフォルトの名無しさん (スップ Sd03-4fWv)
垢版 |
2022/12/27(火) 13:59:01.95ID:WVVp8u06d
>>956
ゴミ持って来んな
しかもそのゴミにもコンパイル前にチェックしてもいい(しなくてもいい)って書いてあるやんけ
>>957
コンパイル出来なかったら問題だとかいう寝言言い出したのはお前の方だろうが
0964デフォルトの名無しさん (ワッチョイ cf9c-iijX)
垢版 |
2022/12/27(火) 14:42:36.98ID:kLAEuBfs0
>>956
未定義動作はc++標準の規定外というだけで、エラーになるかどうかは全く関係無い。エラーにしてもエラーにしなくてもc++標準には違反しない。

www.open-std.org/jtc1/sc22/wg21/docs/standards
N4849.
3.28 未定義の動作
この文書が要求していない動作
[項目への注記 1: 未定義の動作は,この文書が動作の明示的な定義を省略したとき,又はプログラムが誤った構成又は誤ったデータを使用したときに予想されるかもしれない。
未定義動作は,この文書が動作の明示的な定義を省略した場合又はプログラムが誤った構成若しくは誤ったデータを使用した場合に想定される。許容される未定義の動作
予測できない結果をもたらす状況の完全な無視から、翻訳中またはプログラム実行中に特徴的な文書化された方法で動作することまで、許容される未定義動作の範囲があります。
環境に応じて文書化された方法でプログラムの実行を行う(診断メッセージの発行の有無は問わない)。
また、翻訳や実行を終了する(診断メッセージを発行する)こともあります。)
多くの誤ったプログラム構成は、未定義の動作を発生させるものではなく、診断が必要なものである。
定数式の評価は、本書第 4 条から第 15 条で明示的に未定義と指定された動作にはならない。
から第15項(7.7)までに明示的に未定義と指定された動作を示すことはない。- エンディングノート]
0965天災 ◆41t0I.PYBW0z (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 14:53:01.92ID:QO3hLMTW0
>>964
有難う
用語は注意して使わないとね

>>865の質問を正確にすると
前方宣言を自分のソースに追加すると
ビルドはできるが動作が未定義となる設計は本当にあるの?
(もちろんstdは懸案事項なので保留するとしてそれ以外でね)
0967はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/27(火) 15:37:36.05ID:G9AKlNLO0
言語的には仕様通りの解釈をするがそれがそのライブラリにとって想定外であるような、
つまり本来の動作と異なる結果を引きおこすような形での前方宣言がありうるかという意味だろ。
0972デフォルトの名無しさん (ワッチョイ 8d01-s0Sd)
垢版 |
2022/12/27(火) 21:38:26.75ID:Q5qxYeje0
じゃあ、ISOで未定義の時は、コンパイラの仕様を調べて使えば良いのでは?
0974天災 ◆41t0I.PYBW0z (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 22:06:21.35ID:QO3hLMTW0
>>968
確かに前方宣言で挙動変わるね
しかしこのトリッキーな例をもって
前方宣言を自分の管理外の名前空間(std以外でも)に
追加するのが危険と言って良いものかは正直悩む
0975天災 ◆41t0I.PYBW0z (ワッチョイ b101-jXNG)
垢版 |
2022/12/27(火) 22:15:15.29ID:QO3hLMTW0
>>972,973
俺は絶対にstdはいじらないね
0976デフォルトの名無しさん (ワッチョイ 8d01-s0Sd)
垢版 |
2022/12/27(火) 22:17:12.44ID:Q5qxYeje0
じゃあ俺もそうする。
0977デフォルトの名無しさん (ワッチョイ 97ad-dxp0)
垢版 |
2022/12/27(火) 22:18:07.71ID:xkGd3ITG0
自作クラスでendlなどのマニピュレータをオーバーライドするにはstd名前空間に入れるしかないじゃない?
0978デフォルトの名無しさん (ワッチョイ 5b10-WyE/)
垢版 |
2022/12/27(火) 22:19:58.45ID:Kk7zAeAV0
つうかstdが「標準である」と言う設計上前方宣言を禁止したから仕様上未定義動作となっただけの話で
危険だから前方宣言すべきじゃないって話じゃないと思うよ
結果的にコンパイラ側がそれを逆手にとって最適化とか推し進めた形になったとしてもね

前方宣言許さない仕様のライブラリって言うのは危険だからじゃなく
勝手に拡張すること許さないと決めたライブラリであるというだけの話で
0979デフォルトの名無しさん (ワッチョイ 8d01-s0Sd)
垢版 |
2022/12/27(火) 22:24:30.48ID:Q5qxYeje0
>>977
ストリームはホント腹立つよな。
ぶっ飛ばしたくなってきた。
30年くらい怒りが収まらん。
0982デフォルトの名無しさん (ワッチョイ 9fea-ij7E)
垢版 |
2022/12/27(火) 23:26:06.87ID:VvvSD8wK0
ostream と istream の別の建てつけなので、ファイルポインタもこの二つのクラスで別なんだろうと思っていたら、土壇場で、実はファイルポインタは共有していましたぁ
とか勘弁してほしいと痛切におもいましたねえ
0985デフォルトの名無しさん (テテンテンテン MM97-iijX)
垢版 |
2022/12/28(水) 08:09:55.49ID:jVoOqLVQM
>>978
そういうのは「改造c++」とでも言うべきもので、個々の具体的な実装を挙げて話すべき話題。
具体的な実装の無い「改造c++」なんて「オレ言語」でしかないから、話題にしても相手にするヤツは居ないよ。興味無い。
0986デフォルトの名無しさん (アウアウウー Sa1f-SHOq)
垢版 |
2022/12/28(水) 16:02:37.97ID:wx2BQ76Ga
>>981
まさかプロトタイプが30年後も使い続けてるとは思わなかったんだよ
0987はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6d3e-aH43)
垢版 |
2022/12/29(木) 22:47:04.14ID:J2+EgPHK0
>>974
「わからない」という状態が最大のリスクだ。 精査して事情を把握してからやる分にはいいよ。
だけど少なくとも私はいちいちライブラリの細かいことなんて調べたくないし、
細部の事情まで読み解ける自信はないから製作者の意図 (仕様として明示されている範囲) を超える
ような使い方をあえてすることはないだろうという話。 要するに割に合わない。
しなくていいことはせずに済ませられたらそのほうがいいだろ。

割に合うと考えている人がいたとしたら
「んなわけねーだろ。 お前が調べるのに労力をかけてないだけ」
と思うから安易にやっちゃうやつはちょっとナメてるように感じる。

そりゃあ他に打てる手がなければ割に合わなくてもやらざるを得ないことだってあるだろうけどさぁ。
0991デフォルトの名無しさん (ワッチョイ 5328-gB2L)
垢版 |
2022/12/30(金) 13:31:38.92ID:p0azBXIn0
std名前空間への勝手要素追加は未定義動作と書かれているのに
std名前空間内のクラスへのメンバ追加についてはなんで言及が無いのやろうな……
名前空間もクラスもPGの責任分担範囲の区切りみたいなもんで、
第三者に後から勝手に弄られたら設計したPGが困るのは同じだと思うのだけど、
0998デフォルトの名無しさん (ワッチョイ 97ad-dxp0)
垢版 |
2022/12/30(金) 17:36:57.79ID:oiKCiiXa0
後のこと考えて設計するよりも先に手が動くような人じゃないとプログラミングは上達しないよ
1000デフォルトの名無しさん (スプッッ Sddb-tLuz)
垢版 |
2022/12/30(金) 18:20:10.37ID:2kXrfTwwd
昔はさ、ウォーターフォールといって
完璧な設計ができるまでコードに手を出すな
設計が決まったら黙ってそれに従うコードを書け
なんてのがあったけど
前例のないものの完璧な設計なんてほいっとできるのか
現場からのフィードバックを無視なんてできるのか
って反省から今時の方法論ができているわけで

ただし、それを悪用するだけの寄生虫を擁護はしない
10011001
垢版 |
Over 1000Thread
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 60日 3時間 50分 35秒
10021002
垢版 |
Over 1000Thread
5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。


───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────

会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。

▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/

▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php
レス数が1000を超えています。これ以上書き込みはできません。

ニューススポーツなんでも実況