2ちゃんねる スマホ用 ■掲示板に戻る■ 全部 1- 最新50    

■ このスレッドは過去ログ倉庫に格納されています

C++相談室 part162

1 :sage :2022/10/31(月) 14:29:35.57 ID:J5sgTSch0.net
!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

2 :デフォルトの名無しさん :2022/10/31(月) 17:11:42.28 ID:FSs0hrWX0.net
保守です

3 :デフォルトの名無しさん :2022/11/01(火) 07:31:00.75 ID:8mAHYLmxd.net
寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処藪ら柑子の藪柑子パイポパイポ パイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助

4 :デフォルトの名無しさん :2022/11/01(火) 12:22:19.23 ID:LNKvo44sd.net
今更話すことある?

5 :デフォルトの名無しさん :2022/11/03(木) 09:15:40.37 ID:AvIGv7Uk0.net
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...>&&) {}

うーん、困った
どうしよう。。。

6 :デフォルトの名無しさん :2022/11/03(木) 10:13:40.98 ID:GMyBvZ220.net
requires map_t<MAP>でええやん

7 :デフォルトの名無しさん :2022/11/03(木) 10:30:49.88 ID:AvIGv7Uk0.net
あ、そっか
㌧x

一応、報告
template <template<class...> class MAP, class... ARGS> requires map_t<MAP> //OK
void test(MAP<ARGS...>&&) {}

8 :デフォルトの名無しさん :2022/11/03(木) 18:33:03.71 ID:A3AnwOcy0.net
テンプレートにテンプレート重ねて滅茶苦茶する典型

9 :デフォルトの名無しさん :2022/11/03(木) 20:41:25.83 ID:GMyBvZ220.net
AssociativeContainer要件のコンセプトは標準ライブラリには無いんだな
規格上定義してるrequirementは一通り作っとけばいいのに

10 :デフォルトの名無しさん :2022/11/03(木) 22:05:17.66 ID:f0rgVbxY0.net
>>8
でも文法的コンパイラ的には許されている
100段くらい重ねて大丈夫なんじゃなかろうか

11 :はちみつ餃子 :2022/11/03(木) 22:28:39.04 ID:b1nVlp4p0.net
>>10
コンパイラが無限のリソースを使えるわけじゃないから制限があってもいいし、
わかっている制限は文書化するべきということになっている。
https://timsong-cpp.github.io/cppwp/n3337/implimits

言語仕様の側でもどの程度まで処理すべきかという最低限の数値は与えていて
この場合だと
Recursively nested template instantiations [1024].
ってのが当てはまる。
あくまでもガイドラインなのでこれ以下に制限された処理系がないとは言えないんだけど、
1024 が提示されているところで 100 やそこらに制限するような処理系はたぶんあんまりないとは期待できると思う。

12 :デフォルトの名無しさん :2022/11/04(金) 14:22:03.44 ID:MccBwaps0.net
そんなん言い出したら自動変数は合計何バイトまでとか
しょーもないことを規格票に書くハメにならないか?

13 :デフォルトの名無しさん (ワッチョイ 8901-T+yX):2022/11/04(金) 14:28:53.41 ID:I5Ua2kB10.net
GCCとClangの -ftemplate-depth-?? の話?

14 :デフォルトの名無しさん (スッップ Sd33-pLSs):2022/11/04(金) 15:45:10.91 ID:nV9i8Ccmd.net
昔は17だったなその制限

15 :デフォルトの名無しさん :2022/11/04(金) 16:29:55.40 ID:MccBwaps0.net
つーかよ
俺5だけど、あの程度のことで
8みたいなこと言われたのずっこけてる

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

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

テンプレートテンプレート仮引数がわからんだけじゃないのかって邪推しちまいそう

16 :デフォルトの名無しさん :2022/11/04(金) 16:49:46.97 ID:nV9i8Ccmd.net
全然あかんくないと思うよ
8がアホなだけ

17 :デフォルトの名無しさん :2022/11/04(金) 18:04:41.45 ID:I5Ua2kB10.net
話は綺麗に終わってるのに
発展的に関連した話題を振るのならともかく
何で>>8みたいなコメントをいちいち付けるのか俺も理解不能

18 :デフォルトの名無しさん :2022/11/04(金) 18:07:42.31 ID:I5Ua2kB10.net
>>14
そうそう昔はこれを付けないで17超えるとエラーが出てた
-ftemplate-depth-100 くらいで使ってたけど
いまはデフォルトで1024になってるのね

19 :はちみつ餃子 :2022/11/04(金) 19:44:51.78 ID:lXYNWX4U0.net
制限はあくまでも「深さ」であって「回数」ではないので上手いこと変形するのも技の内だったんだよな……。
遊びでやるならきつめの制限も楽しいんだけどね。

20 :デフォルトの名無しさん :2022/11/05(土) 15:23:46.47 ID:6woT7hPv0.net
自動的に解釈されるテンプレート引数で
値渡しじゃなく参照渡しと解釈させる方法ってありますかね?

21 :デフォルトの名無しさん :2022/11/05(土) 15:33:58.60 ID:95t5abQGd.net
std::ref
std::cref

22 :デフォルトの名無しさん :2022/11/05(土) 15:40:28.55 ID:6woT7hPv0.net
あるんですねぇ
ありがとうございます

23 :デフォルトの名無しさん :2022/11/07(月) 14:57:30.80 ID:8LbwGvMzM.net
明示的な型変換が可能か調べる方法ってありますか?
暗黙的ならis_convertibleが使えるのですが…

std::is_convertible<std::shared_ptr<void>, bool>::value; // trueになってほしい

24 :デフォルトの名無しさん :2022/11/07(月) 16:58:07.91 ID:2UaeFBkad.net
is_constructibleを使う

25 :デフォルトの名無しさん :2022/11/07(月) 17:32:26.98 ID:unROdsfFM.net
>>23
std::is_constructible<bool, std::shared_ptr<void>>::value

ありがとうございました。

26 :デフォルトの名無しさん :2022/11/07(月) 17:32:50.90 ID:unROdsfFM.net
>>24
ありがとうございました。

27 :デフォルトの名無しさん :2022/11/09(水) 10:37:27.83 ID:uQIa4jnTp.net
質問です
マネージドとかアンマネージドとかMSの呪いですか?

28 :デフォルトの名無しさん :2022/11/09(水) 11:23:16.37 ID:GzNJb2MKM.net
プログラミング言語 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 );
・・・
}
ここで問題となるのは、以下のどちらの方法で解釈されているかということです。
[続く]

29 :デフォルトの名無しさん :2022/11/09(水) 11:24:30.65 ID:GzNJb2MKM.net
>>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)だと上手く行かない気がします。
[続く]

30 :デフォルトの名無しさん :2022/11/09(水) 11:25:24.81 ID:GzNJb2MKM.net
>>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へと変換される。

31 :デフォルトの名無しさん :2022/11/09(水) 16:50:18.10 ID:XEaxVtCg0.net
大体わかってそうだけど
{…}をinitializer_list<Entry>として解釈しようと試みる→中身の{"David Hyme",123456}とかをEntry型に暗黙変換しようと試みる→全部変換できれば成功
Entryがexplicit Entry(string, int);を持ってると暗黙変換できなくて失敗するようになる

32 :デフォルトの名無しさん :2022/11/10(木) 00:59:56.86 ID:8S99EFBAM.net
>>31
vector<T>クラスのコンストラクタに、initializer_list<T> 以外の引数を
持つものが存在していた場合、どういう優先順位でコンストラクタが選ばれて
いくのでしょうか。
コンパイラは、最初に初期化子の {・・・} の部分のカンマで区切られた中身の
個数を数えてから、その個数によってどのコンストラクタを選ぶかを決めますか?

33 :デフォルトの名無しさん :2022/11/10(木) 01:07:30.02 ID:8S99EFBAM.net
>>32
仮にそうだとすると、コンパイラの内部では、
1. vector<Entty> phone_book の宣言の型である vector<Entty>を把握。
2. = の右側の初期化子の部分の{}の中の個数など大まかな特徴を掴む。
3. 2の特徴に基いて最適なvector<Entry>のコンストラクタを探す。
4. = の右側の部分を3.のコンストラクタに基いて解釈/変換する。
という少なくとも4段階の工程を得ていることになりそうですが、随分と
特殊な解釈の仕方ですね。
通常の式ならば、このように「いったりきたり」はしないものですが。

34 :デフォルトの名無しさん :2022/11/10(木) 07:25:48.25 ID:JLZuLXt50.net
そこは通常のオーバーロード解決と同じだけど何が気に食わないの?
f(int)とf(int,int)があってf(1,2)を解決するときに「先に引数が2個あることをチェックするなんてインチキだ!」って発狂されても

35 :デフォルトの名無しさん :2022/11/10(木) 12:27:18.30 ID:Ma0XsUW1M.net
>>34
しかし、その場合、どの関数を呼び出すかが決定されてから後に、パラメータ(実引数)
の意味解釈は変化せず、実引数の解釈は同じで、必要あらば関数の仮引数へとcastされるだけです。
ところが、今回の初期化子の場合は、実引数の大体の様子が調査された後に、
どのコンストラクタを使うかが決定。コンストラクタが決定された後に、実引数の
意味解釈まで変わります。

36 :デフォルトの名無しさん :2022/11/10(木) 12:30:32.91 ID:Ma0XsUW1M.net
>>35
[補足]
前半の通常の関数の場合、コンパイラの内部で隠れてcastされるという訳ではなく、
必要あらばちゃんとcastに必要な「変換関数」が呼び出されることまで決まって
おり、マシン語レベルで変換関数を呼び出だすcall文が生成され、その中で
変換に必要なマシン語の列が実行されます。
ところが、後半の初期化子の場合、その変換関数が呼び出されない可能性が高い
です。なぜなら、変換ではなく、最初からのコンストとラクタの仮引数の
型に合わせて意味解釈されて、いきなりその型としてコンパイルされるためです。

37 :デフォルトの名無しさん :2022/11/10(木) 12:33:49.93 ID:Ma0XsUW1M.net
>>36
[補足2]
気に食わないのではなく、不規則変化というか、C++の一般法則とは異なる
法則が流れているようで、難しいな、と思ったまでです。

38 :デフォルトの名無しさん :2022/11/10(木) 12:36:36.70 ID:43j6CzLZF.net
これvector<Entry>に
std::array<Entry,3>とか
std::tuple<std::pair<const char*, int>, std::pair<const char*, int>, std::pair<const char*, int>>
とか受け取るコンストラクタが追加されてたらまた話変わったりするよね

一応全部合法的に受け取れるはずだから、
コンパイラはどう解決するべきかってのを >>28 は聞きたいんだと思う

39 :デフォルトの名無しさん :2022/11/10(木) 12:40:22.21 ID:IDnNuz1Ud.net
なんか書き込んでからどっちもコンパイル通らないような気がしてきた
忘れてくれ

40 :デフォルトの名無しさん :2022/11/10(木) 13:04:32.16 ID:kKaeKygLd.net
>>38
その場合は曖昧だって怒られるだけ

41 :デフォルトの名無しさん :2022/11/10(木) 13:24:31.23 ID:WlLaCVUwd.net
初期化子をコンストラクタのオーバーロード候補(静的に決まる)にそれぞれ適合させてみて、どれもダメならエラー、複数当てはまるなら優先度に従って1個に絞れたらそれを選択、曖昧ならエラー

初期化子や優先度の複雑怪奇なルール詳細の事ならともかく、この大枠の話の何がそんなに原則外れで難しいと思ってるのか正直さっぱりわからない

42 :デフォルトの名無しさん :2022/11/10(木) 13:24:55.21 ID:Ma0XsUW1M.net
>>37
[補足4]
fという名前だが仮引数の型が異なる持つ関数f()が複数ある場合は、
f(a);
と書いた場合、aの部分が完全に意味解釈されて、aの型が完全に決まってから、
どのf()が呼び出されるかを選択。
選択されたf()の仮引数の型Tと実引数aの型を比較して、異なっていれば、
aの型をTに変換する変換関数を呼び出し、変換後の値を関数f()の引数として
関数f()を呼び出す。

ところが、初期化子の場合、
T v = b;
と書くと、bの型を軽く調査するが、完全には b が意味解釈される前にどの T のコンストラクタ
を呼び出すべきかの調査が始まる。その時点では、bの型は完全には決まってない。

43 :デフォルトの名無しさん :2022/11/10(木) 13:28:29.70 ID:Ma0XsUW1M.net
>>41
>初期化子をコンストラクタのオーバーロード候補(静的に決まる)にそれぞれ適合させてみて、どれもダメならエラー、複数当てはまるなら優先度に従って1個に絞れたらそれを選択、曖昧ならエラー
Tのどのコンストラクタを使うかが決まるまでは、初期化子の中身の型が決まりません。
なので、総当り的にチェックすることが不可能だということになります。
(原因と結果が逆なので)。
なお、Tのどのコンストラクタを使うかを決める際に、初期化子のある程度の様子は
必要になりますのでややこしくなっています。

44 :デフォルトの名無しさん :2022/11/10(木) 14:13:26.85 ID:99QPf7Vaa.net
>>36
関数だって定数(もしくは定数になる式)渡したら変換関数なんか呼ばずに変換後の値を渡すようにコンパイルするだろ

45 :デフォルトの名無しさん :2022/11/10(木) 15:49:32.45 ID:kY0Aveh/d.net
>>43
型が決まらないって何のこっちゃ
君の例だと"David Hyme"はconst char*だし123456はintだし、
{"David Hyme",123456}はEntry(に集成体初期化で暗黙変換可能)で、他の要素も全部そうだから初期化子全体はinitializer_list<Entry>(に暗黙変換可能)なのでvector(initializer_list<Entry>)が適合可能、って全部静的に決まる話だぞ(正確にはもっとややこしいけど)
どこに動的型が出てくると思った?

46 :デフォルトの名無しさん :2022/11/10(木) 21:41:21.36 ID:lrIHTbD+0.net
自分の認識と実際の動作の間に食い違いがあることを質問したのに
その認識の間違いを指摘されても認めたくない人って厄介だね。

47 :デフォルトの名無しさん :2022/11/10(木) 21:44:22.55 ID:xu9+brpFp.net
プログラムは書いた通りにしか動かない

って奴だな

48 :デフォルトの名無しさん :2022/11/10(木) 21:59:32.65 ID:ycxEOHBI0.net
自分の認識の通りのコンパイラを作るってんならご自由にだが
そうでない以上認識を改める他なかろう

49 :デフォルトの名無しさん :2022/11/10(木) 22:00:55.26 ID:8bOle1Do0.net
依存性逆転の原則または依存関係逆転の原則

50 :デフォルトの名無しさん :2022/11/10(木) 22:21:23.00 ID:XJxScCwYM.net
>>45
動的な型のことは一切言及していません。
私のIQは170以上あるので、普通のプログラマには質問の意味が理解できてない可能性があります。

51 :デフォルトの名無しさん :2022/11/10(木) 22:22:55.08 ID:XJxScCwYM.net
2ch/5chでレベルが高い質問をすると、バッシングを受ける傾向が有ります。

52 :デフォルトの名無しさん :2022/11/10(木) 22:23:43.35 ID:xu9+brpFp.net
頭が良い人なら、馬鹿にも分かる説明も難なくこなすんだがなぁ
自称してるだけの馬鹿なら意味不明な話を相手の理解力のせいにするんだよなぁ

53 :デフォルトの名無しさん :2022/11/10(木) 22:25:12.06 ID:XJxScCwYM.net
>>45
例えば、class定義の中身Xが同じでも、class A {X} と class B {X} では別の型です。
その意味で、型が決まってないのです。
繰り返しますが、あなたはC言語の基礎が理解出来てないか、または、IQが
この質問に対して足りてない可能性があります。

54 :デフォルトの名無しさん :2022/11/10(木) 22:26:30.44 ID:XJxScCwYM.net
>>52
逆も有ります。
ちなみに、私は実世界で天才だと言われたことが何度も有ります。

55 :デフォルトの名無しさん :2022/11/10(木) 22:29:41.43 ID:XJxScCwYM.net
>>53
[補足]
{"aaa",1234}は、>>28のEntryとよく似た方では有りますが、コンパイラ内部では
Entryとは認識されません。仮に、
struct EntryB { const char *name, int number; };
とすれば、{"aaa",1234}は、中身の型としてはEntryBと全く同じと言えますが、
EntryBではないのです。
これが理解できないならば、C言語の基礎が理解出来てないので、質問の
意味が理解できないでしょう。

56 :デフォルトの名無しさん :2022/11/10(木) 22:34:40.81 ID:XJxScCwYM.net
なお、数学的な言葉に慣れてない人は私の質問が哲学的な抽象論の様に聞こえて
頭が悪い人が変なことをいっているように聞こえたかも知れません。

57 :デフォルトの名無しさん :2022/11/10(木) 23:38:43.51 ID:lrIHTbD+0.net
>>53
>例えば、class定義の中身Xが同じでも、class A {X} と class B {X} では別の型です。

nominal typing な世界ではたしかにAとBは別の型だが無名の{X}はAとBどちらにも一致する。

58 :デフォルトの名無しさん :2022/11/10(木) 23:56:40.35 ID:QHBEGLKOa.net
>>54
最近は体調どうよ

59 :デフォルトの名無しさん :2022/11/11(金) 00:01:29.20 ID:J8vKnsQy0.net
あー君が何を勘違いしてるのか分かってきた
「初期化子`{"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)


キチガイみたいだから優しく教えるのはこれで最後にする
すまんかったね

60 :デフォルトの名無しさん :2022/11/11(金) 00:16:31.96 ID:NMTpQElqM.net
>>59
型を持ってるわけじゃないのは当然なのに、あなたが「動的型」というこっちが
言ってないことを勝手に妄想しだしたので、基礎から解説したまでです。
こっちの方が圧倒的に頭がいいので、食い違うのです。

61 :デフォルトの名無しさん :2022/11/11(金) 00:17:28.31 ID:NMTpQElqM.net
馬鹿は自分が馬鹿だと気付かないんです。
質問の意味すら分かってないのに質問に答えようとしてくる。

62 :デフォルトの名無しさん :2022/11/11(金) 00:22:09.88 ID:NMTpQElqM.net
>>59
このような場合にC++では型が静的に決まるのは当たり前。
あなたこそ、動的言語を前提にしているように思える。
そういうことではなくて、コンパイラが内部でどのような順序で「静的に」翻訳作業を
行なっているかを質問している。
コンパイラ内部では型を持って無くても、構文ツリーや色々な形でデータを
持っているが、仕様では、その順序までも決まってないとコンパイラで非互換性が
出てきてしまうし、何より、C++では演算子のオーバーロードなども出来る訳
だから、コンパイラの内部的な解釈の順序まで厳密に仕様化されてなければ、
一般プログラマも混乱が生じる。
その事を聞いている。

63 :デフォルトの名無しさん :2022/11/11(金) 00:26:17.38 ID:NMTpQElqM.net
>>62
[補足]
JSなどの動的で初心者ならば、「大体」で理解していればそれで問題無い事が
多いだろうが、C++では、テンプレートもあればoperator+()演算子や型変換
演算子などをオーバーロードできるから、「大体」では駄目で、非常に細かな
コンパイルの順序や解釈の流れまでが言語の仕様書に厳密に書いてなければ
正しいアプリケーションコードを書くことが出来ないことがある。
「直感的に簡単に理解できるのに、何この馬鹿は聞いているんだ?」
などと思っているとすれば、大間違いだ。

64 :デフォルトの名無しさん :2022/11/11(金) 00:28:53.35 ID:L/uUC/Rw0.net
質問はしたのだから、回答を待っていればいいだろうに
何でまた独り言を延々と書いてるのか、不思議だ
書くなら自分の日記帳に書けばいいのでは

65 :デフォルトの名無しさん :2022/11/11(金) 00:32:42.01 ID:NMTpQElqM.net
>>63
[補足]
>>28で、phone_bookの初期化子について、「直感的に」理解できたら
それで十分、などと考えている人は、馬鹿なので質問には答えないで下さい。
C++コンパイラは、そのように大体で動作しているのではなく、パターン
に当てはめて順序を追ってコンパイルを進めていきますが、その順序や
解釈の仕方がC++03の時代とはかなり違っているように思えたから
質問したのです。
例えば、>>28は単なる例であって、これの応用として非常に複雑なコードを
書いた場合でも、コンパイラはなんたかの単純な法則に従って厳密に翻訳していきます。
その正確な規則が分からないから聞いているのです。

66 :デフォルトの名無しさん :2022/11/11(金) 00:33:22.29 ID:NMTpQElqM.net
>>64
馬鹿な人が茶々入れしてきたので、排除する努力をしています。

67 :デフォルトの名無しさん :2022/11/11(金) 00:40:51.17 ID:NMTpQElqM.net
>>59
>Entryのようにstringとintを持った構造体なら集成体初期化になるし、
今回の例では、vector<Entry>型の初期化ですので、そんな単純ではありません。
vector<T,A>テンプレートのコンストラクタが呼び出されるはずです。
しかも、コンストラクタの種類が沢山ありますから、それを選ばなくてはなりません。
Entry a = {"xxx",1234};
ならば集成体初期化ですから、コンストラクタを選ぶ工程は無いはずですから、
比較的単純です。
ところが、今回の場合は、コンストラクタの選択から始まります。
しかし、初期化子自体の型が中途半端な状態でコンストラクタを選ぶ必要が
ありそうなので質問しているのです。

C++03で、x+y書いた場合、xとyの型が決まった後で、operator+(U,T)演算子を探します。
ところが今回の場合、初期化子の部分の型が中途半端な状態なので、コンストラクタを探す
ための手がかりが中途半端にしかないのです。

68 :デフォルトの名無しさん :2022/11/11(金) 00:45:48.11 ID:NMTpQElqM.net
>>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}には、ある意味では「型が存在してない」ので
通常のように探すことは出来ないのです。

69 :デフォルトの名無しさん :2022/11/11(金) 00:48:44.75 ID:J8vKnsQy0.net
>>65
正確な規則が知りたいのに規格に当たることすら思いつかないのか自称天才のボンクラ様ってのは
9.4 Initializers [dcl.init](C++20公開ドラフトN4861、正規の規格がいいなら自分で買え)を見ればいいよ
誰でも読めば分かるように書いてある規格を天才様が理解できないなんてありえないから以降質問禁止な

70 :デフォルトの名無しさん :2022/11/11(金) 00:55:21.61 ID:NMTpQElqM.net
>>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の構造体型
としての処理が入ります。
これが理解できない人は質問には答えないで下さい。混乱の元になります。

71 :デフォルトの名無しさん :2022/11/11(金) 00:56:13.87 ID:NMTpQElqM.net
>>69
そんな言い方されれば質問サイトの意味が無いわけです。

72 :デフォルトの名無しさん :2022/11/11(金) 00:59:02.50 ID:J8vKnsQy0.net
>>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>)しか当てはまるものがないので、じゃあこれだとオーバーロードを解決するわけだ
コンパイラのやってることなんて基本的にこれだけだ、実に単純な話だ
こんな単純なこともわからずグチグチグチグチとお前は本当に無能だな

73 :デフォルトの名無しさん :2022/11/11(金) 01:02:30.49 ID:NMTpQElqM.net
>>72
その探し方は、普通の関数のオーバーロード解決とは異なっていますね。
しかも、あなたの言っているほど単純じゃない。
実際は、優先順位があり、先に優先順位の低いものが見つかって、後から
優先順位が高いものが見つかっても、後の方が優先される。

あなたが馬鹿なのは、単純に考えすぎていることだ。

74 :デフォルトの名無しさん :2022/11/11(金) 01:03:31.20 ID:J8vKnsQy0.net
>>71
なんで答えが書かれた文書が誰でも読めるように公開されてるのに、わざわざ自分より劣った人間に答えを求めるの?
お前天才なんだろ?ここの誰よりも賢いんだろ?
消えな

75 :デフォルトの名無しさん :2022/11/11(金) 01:04:06.86 ID:hvQf6BDd0.net
>>74
すまんがお前が消えてほしい
相手するからつけあがる

76 :デフォルトの名無しさん :2022/11/11(金) 01:05:05.21 ID:NMTpQElqM.net
>>73
[補足]
なお、関数のオーバーロード解決でも、「変換できるかどうか」とかそんな単純な
ものじゃないです。
例えば、T a{x} のように{}が書いてあれば、中味が1個しか書いてなくても、
initializer_list が優先される、などと決まってます。

77 :デフォルトの名無しさん :2022/11/11(金) 01:05:24.11 ID:J8vKnsQy0.net
>>73
だから正確なのが知りたいなら規格読めやボケカス
お前のゴミ虫みたいな脳みそに合わせてわざわざ単純化してやったのに何だその物言いは無礼者の恥知らずが

78 :デフォルトの名無しさん :2022/11/11(金) 01:06:38.58 ID:NMTpQElqM.net
>>74
俺よりC++を知っている人だってこの世にいるから質問してる。
それでは質問サイトの意味がない。
調べればわかることでも知ってる人に聞いたほうが早い。

79 :デフォルトの名無しさん :2022/11/11(金) 01:07:31.06 ID:J8vKnsQy0.net
>>76
T a{x}ってそれ関数じゃなくて変数定義ですよ
そんな区別もつかないレベルじゃ規格書なんて早かったかなごめんね
でもそれも規格書に書いてあるから読んで勉強しろ

80 :デフォルトの名無しさん :2022/11/11(金) 01:07:50.72 ID:NMTpQElqM.net
>>77
あなたみたいなのが日本を衰退させている。
自分が頭がいいと思い込んでいるがかなり間違ってるし、レベルが低い。
そして、あなたの周りにはレベルの低い人しか回りに居ないから勘違いが
直らない。

81 :デフォルトの名無しさん :2022/11/11(金) 01:08:28.22 ID:NMTpQElqM.net
>>79
アホですか。
コンストラクタを探す話をしている。

82 :デフォルトの名無しさん :2022/11/11(金) 01:09:07.49 ID:J8vKnsQy0.net
>>78
ここで俺や他の人が説明してあげてる内容すら理解できないなら、規格書を泣きながら読むか死んだほうが早いと思うよ

83 :デフォルトの名無しさん :2022/11/11(金) 01:10:04.92 ID:NMTpQElqM.net
日本は分断化が激しい社会だ。
カシコが一部に集まり、アホがあほ同士集まっている。
だから自覚できない。
そういう社会にしてしまっていることが問題。

84 :デフォルトの名無しさん :2022/11/11(金) 01:10:52.44 ID:J8vKnsQy0.net
>>81
1行目のせいで関数のオーバーロード解決の話をしてるもんだと思ったよ
どうやらC++以前に日本語すら不自由なようだね

85 :デフォルトの名無しさん :2022/11/11(金) 01:11:25.32 ID:NMTpQElqM.net
>>82
お前は理解できてないのに質問に答えようとしている。
いつもは質問のレベルが低いから答えられているんだろうが、今回は
お前の能力を超えている。
そしていつもの調子で質問者をレベルが低いと思い込んでいるから
馬鹿にした態度をとる。

86 :デフォルトの名無しさん :2022/11/11(金) 01:11:57.99 ID:NMTpQElqM.net
>>84
お前に言われたくない。

87 :デフォルトの名無しさん :2022/11/11(金) 01:14:33.80 ID:NMTpQElqM.net
>>82
「してあげている」
って、おまえの思ってる直感的理解と、俺の求めている理解とは次元が違う。
お前は、いっぱんぴーぽーとしてC++を使えてもそれ以上はできないだろう。

88 :デフォルトの名無しさん :2022/11/11(金) 01:16:18.16 ID:J8vKnsQy0.net
もう終わりにするけど、俺の説明が間違ってるって言うならそれは規格と主要コンパイラの実装が間違ってるってことだから
ISOとベンダーに報告しときなよ

>>75
ごめんなさいみなさん久しぶりに面白いおもちゃだったのでつい

89 :デフォルトの名無しさん :2022/11/11(金) 02:19:52.16 ID:tp0srwYgd.net
キャラ剥がれてきてて草

90 :デフォルトの名無しさん :2022/11/11(金) 05:29:55.03 ID:wl59B58M0.net
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が大きいときは現実的でないので考えておりません。

91 :デフォルトの名無しさん :2022/11/11(金) 07:32:36.01 ID:fbtAWiSRH.net
>>54
逆はないと思いますよ

92 :デフォルトの名無しさん :2022/11/11(金) 07:44:40.78 ID:J8vKnsQy0.net
>>90
残念ながらarrayで初期化時にやるのは無理
arrayは組み込み配列と同じ初期化方法(集成体初期化)しか出来ないように意図的に設計されてて特別なコンストラクタを持たない
だからarray::fill()が用意されてるので普通はそれを使う
どうしてもその場で要素のコンストラクタを直接呼びたいなら一回構築してから要素ごとにデストラクタ→placement newを呼ぶしかない
最初のデフォルト構築も許せないならarray(と組み込み配列)を使うのは諦めよう

93 :デフォルトの名無しさん :2022/11/11(金) 15:28:43.83 ID:x9X8FiGQM.net
>>91
いくらアインシュタインが相対性理論を説明しても、一般人には理解できない。
どんなに天才でも、説明できない事柄がある。

94 :デフォルトの名無しさん :2022/11/11(金) 19:19:22.94 ID:+I+8FBiLd.net
天才ほど説明が下手だね
天賦の才に頼らず這い上がった苦労人タイプの
説明のほうが一般人には分かりやすい

95 :デフォルトの名無しさん :2022/11/11(金) 20:11:09.74 ID:MfyOP1HR0.net
わかった気になるだけってやつね
完全に理解する必要のない一般人ならそれもあり

96 :デフォルトの名無しさん :2022/11/11(金) 20:47:56.26 ID:76yLxZ0B0.net
誰かを見下していなきゃ自分を保てない小さいやつ

97 :デフォルトの名無しさん :2022/11/11(金) 23:42:57.00 ID:jawQM+EmM.net
確かに右辺値参照あたりの仕組みはコピー減らそうという意図が感じられる割に徹底しようとするとstd::arrayとかのctorで足元すくわれがち

98 :デフォルトの名無しさん (ワッチョイ 7501-WFXv):2022/11/12(土) 01:01:47.32 ID:0JLM8m+J0.net
ワッチョイつけると炎上しなくて良いね

99 :デフォルトの名無しさん :2022/11/12(土) 07:48:03.70 ID:GOjTxZ8j0.net
arrayは組み込み配列の糞さ緩和が目的なので糞が多少まろび出るのは仕方ないんよね

100 :デフォルトの名無しさん :2022/11/12(土) 09:59:28.06 ID:D5o/xiXJ0.net
>>92
collectionで初期化も無理なんだ?
せめてvectorで初期化できるなら良かったのにね

総レス数 1001
307 KB
新着レスの表示

掲示板に戻る 全部 前100 次100 最新50
read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★