23/05/09 17:29:42.12 fBzPCnLFd.net
>>1
乙
3:デフォルトの名無しさん (ワッチョイ df01-ouLR)
23/05/10 05:46:16.13 v0BqkWXe0.net
>>2
よく見たらそれ乙じゃなくてポニーテールやん
4:デフォルトの名無しさん (スプッッ Sd97-Itme)
23/05/10 07:28:21.43 htltMOsRd.net
どゆこと?
5:デフォルトの名無しさん (テテンテンテン MMde-qVtI)
23/05/12 20:00:57.96 mYlAeNCAM.net
class template みたいなノリで、namespace templateとかできないかね。
ユーザーカスタマイズくらいしかメリット無いけど。
6:デフォルトの名無しさん (ワッチョイ 6f9a-syTp)
23/05/13 07:51:55.71 JxNjXH3v0.net
ある整数のペアが既に出てきたかどうかを管理したいのですが、
安直に unordered_set(pair<int, int>> としたら、これはハッシュ関数を定義してあげないと
使えないんですね。
ネット上で見かけた良さげなハッシュ関数の例をコピーする手もあるのですが、
これ以外で楽なやり方(データ型)ってありますかね?
7:デフォルトの名無しさん (テテンテンテン MM7f-hs0w)
23/05/13 08:05:00.58 qcT1eyp6M.net
職業プログラマに聞きたいんだけど
自分でソフト屋なんて言ってるけど、ほぼ全てを外注に投げて自分ではろくに書けないなんての普通のことなの?
今年から社会人になったんだけど、先輩たちのレベルが低すぎて失笑してる日々です。
c言語、クラスという単語をドヤ顔で宣ってる先輩達。
classを解釈できるcコンパイラがあるのかな
8:デフォルトの名無しさん (ワッチョイ cf34-+/XS)
23/05/13 08:10:28.77 Er9DBy9d0.net
俺は自分がそうだったら恥ずかしくてプログラマなんて名乗れないけど
世の中には色んな人がいるからね
まあ俺の価値観では普通じゃない
クラス、つまりオブジェクト指向は何言語を使うかじゃなく頭の中の考え方だから
++じゃないCでも使っていい用語だよ
9:デフォルトの名無しさん (ワッチョイ 6f9a-syTp)
23/05/13 08:20:18.41 JxNjXH3v0.net
>>6
ちなみにPythonだと辞書や集合にタプルをデフォで入れられるんですよね...
C++も同様のサポートをして欲しかった気が
10:デフォルトの名無しさん (ワッチョイ 3302-Cej3)
23/05/13 08:32:20.51 /V+1J/0r0.net
>>7
板違い。マ板へ行け
あと5chは不満のはけ口じゃない。そういうのはママにでも慰めてもらえ
11:デフォルトの名無しさん (スップ Sd1f-ammQ)
23/05/13 09:16:37.00 uFhfbSODd.net
>>6
単に vector とかのコンテナに入れて find とかで既出判定すればいいんじゃないかな。
12:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ ff3e-Phjm)
23/05/13 09:44:38.89 vqN1nVlv0.net
>>11
数が特に少ないときならそれでもいいけど
普通に考えたら実行コストが大きすぎるだろう。
13:デフォルトの名無しさん (ワッチョイ cf34-+/XS)
23/05/13 09:49:39.77 Er9DBy9d0.net
ハッシュ関数を定義してあげないと使えないって
定義すれば使えるだろ
何が問題なんだ?
14:デフォルトの名無しさん (アウアウエー Sadf-OfPZ)
23/05/13 10:30:48.84 W/YCRtGia.net
単にset<int, int>じゃダメなの?
場合によっちゃあmap<int, set<int>>のほうが容量ケチれそうだけど?
URLリンク(ideone.com)
{
std::set<std::pair<int, int>> s;
s.emplace(1, 1);
s.emplace(1, 2);
auto f = [&s](int a, int b) {
return s.find(std::pair<int, int>(a, b)) != s.end();
//return s.contains(std::pair<int, int>(a, b));
};
std::cout << f(1, 1) << f(1, 2) << f(0, 1) << std::endl;
}
{
std::map<int, std::set<int>> m;
m[1].insert(1);
m[1].insert(2);
auto f = [&m](int a, int b) {
return m.find(a) != m.end() && m[a].find(b) != m[a].end();
//return m.contains(a) && m[a].contains(b);
};
std::cout << f(1, 1) << f(1, 2) << f(0, 1) << std::endl;
}
15:デフォルトの名無しさん (ワッチョイ f37c-rSo2)
23/05/13 11:16:03.77 giA7vv3r0.net
後者だったらstd::multimapでよくね
unorderedでもいいけど
16:デフォルトの名無しさん (アウアウウー Sa67-ayqt)
23/05/13 13:46:15.98 0/cn7SoCa.net
>>7
WNDCLASS
RegisterClass
UnregisterClass
WNDCLASSEX
RegisterClassEx
GetClassName
GetClassLong
SetClassLong
GetWindowClass
17:デフォルトの名無しさん (テテンテンテン MM7f-hs0w)
23/05/13 19:14:51.96 23Ow1LiAM.net
>>16
君もc++を学習しなおせ
18:デフォルトの名無しさん (スップ Sd1f-MiYm)
23/05/13 19:17:32.52 acArdvJWd.net
>>7
ソフト屋という大きなカテゴリの中でコーダーとは役割が違うだけでコーディングスキルだけを見て優劣を考えるのは短絡的な判断だよ
必要なスキルなんて立ち位置次第で全く異なるんだから
19:デフォルトの名無しさん (スプッッ Sd1f-zj+H)
23/05/13 19:23:38.16 lAh8QD2cd.net
コード書けないリーダーは事務方に徹してくれるなら別にいいんだよ
そうじゃないやつが迷惑ってだけ
コーダーをバカにするやつはすべてこれ
20:デフォルトの名無しさん (ワッチョイ 6f9a-syTp)
23/05/13 19:32:33.50 JxNjXH3v0.net
>>13
よく使うものはシステム側でハッシュ関数を用意してくれると助かるな、的な
あともしショボいハッシュ関数を使ったら性能が落ちますし、ってそれも自己責任かw
>>14
setは悪くないですね。ただパフォーマンスにシビアになる場合はunordered_の方を
使いたいかなと。こちらもちゃんとしたハッシュが前提になりますが
21:デフォルトの名無しさん (オイコラミネオ MMc7-ZkZz)
23/05/13 21:58:43.54 TFo/sDKRM.net
int int → long
何にでも突っ込め
22:デフォルトの名無しさん (ワッチョイ 73da-M4GN)
23/05/13 22:42:01.19 2eXxQqWR0.net
long long int
23:デフォルトの名無しさん (ワッチョイ 6f9a-syTp)
23/05/13 23:57:15.63 JxNjXH3v0.net
>>21 >>22
片方の値をシフトして足すということですよね? 確かにアイデアですね
似たような感じでint -> intのマップをソートするというのを見たことが
24:デフォルトの名無しさん (ワッチョイ 335f-GJof)
23/05/14 00:07:36.91 QmAlZPFj0.net
何も考えないでboost::combine_hash使っとけばいい
25:デフォルトの名無しさん (ワッチョイ f37c-rSo2)
23/05/14 00:50:39.86 uyb9YL620.net
どうせ整数のハッシュなんて値そのものだし
26:デフォルトの名無しさん (ワッチョイ 73da-M4GN)
23/05/14 00:58:25.21 hOK4knnB0.net
よくあるサンプルが (x * 12345)%n
27:デフォルトの名無しさん (ワッチョイ 73da-M4GN)
23/05/14 01:15:07.44 hOK4knnB0.net
いや、適当杉田わ
long int v=0;
for(auto c : int_array)
v += v*12345 + c ;
return v%hash_size;
28:デフォルトの名無しさん (ワッチョイ 73da-M4GN)
23/05/14 01:16:46.06 hOK4knnB0.net
いや、こうか
long int v=0;
for(auto c : int_array)
v*=12345, v+=c ;
return v%hash_size;
29:デフォルトの名無しさん (ワッチョイ cf34-TSnC)
23/05/14 06:44:54.29 YUNKAbGY0.net
template <>
struct std::hash<std::pair<int, int>>
{
static constexpr std::size_t size = sizeof(int) * 2;
using result_type = std::bitset<size * CHAR_BIT>;
result_type operator()(const std::pair<int, int>& val) const
{
result_type ret;
ret |= result_type(get<0>(val));
ret |= result_type(get<1>(val));
return ret;
}
};
30:デフォルトの名無しさん (ワッチョイ cf34-TSnC)
23/05/14 06:47:52.52 YUNKAbGY0.net
もとい
ret |= result_type(get<0>(val));
ret <<= sizeof(int) * CHAR_BIT; //fix
ret |= result_type(get<1>(val));
31:デフォルトの名無しさん (ワッチョイ 6f9a-syTp)
23/05/14 10:45:03.83 28vpFfrh0.net
シフト演算が必要なのは、負の整数の場合が
あと、問題のサイズによってはハッシュの速度も気になるなあと
32:デフォルトの名無しさん (オイコラミネオ MMc7-ZkZz)
23/05/14 13:45:27.63 pb1Dbmn7M.net
この流れ…
小学生の頃の自分はもちろんc知らなかったけど
このスレでああだこうだ言ってる人間達よりは使える人間だったのかなと
33:デフォルトの名無しさん (ワッチョイ 7f28-HoHV)
23/05/14 13:47:15.07 mysDM4PT0.net
負の整数を論理演算と組み合わせるときはオフセットして非負の範囲にしてから符号無し型にして唐論理演算したら安心、
取り出すときは(論理演算して切り出した後)逆オフセットで元に戻る
全ての過程で符号つき整数の右シフトが陽に現れずに済む
34:デフォルトの名無しさん (ワッチョイ 7f28-HoHV)
23/05/14 13:52:34.35 mysDM4PT0.net
しつれい
>オフセットして非負の範囲にしてから符号無し型
この処理順序で良いのは {扱う整数|<std::numeric_limits<オフセットするときの整数型>::max()のときはこれで良いが、
=の場合は符号無しにしてからオフセットする
全てが調和する、
35:デフォルトの名無しさん (オイコラミネオ MMc7-ZkZz)
23/05/14 13:53:38.30 pb1Dbmn7M.net
こんなの秒で解決するだろ
ごちゃごちゃ言うようなものなの?
36:デフォルトの名無しさん (ワッチョイ 835f-Phjm)
23/05/14 17:24:37.15 oi9EHG/70.net
こんなの秒でスルーするだろ
ごちゃごちゃ言うようなものなの?
37:デフォルトの名無しさん (スップー Sd1f-HMPm)
23/05/14 18:28:37.27 f2qVMn0Gd.net
スルー出来てない人に言われましても
38:デフォルトの名無しさん (ワッチョイ cf34-TSnC)
23/05/14 21:34:32.36 YUNKAbGY0.net
ヒントじゃあかんのね
100%完全なコードを提供しないとクレームつくわけか
# 若旦はん、やってて恥ずかしおまへんか?
39:デフォルトの名無しさん
23/05/16 15:18:28.27 cdgpde7Q0.net
教えてもらえないでしょうか
c++で
クラスを作って関数を書いています。
大きくなり、可読性が悪いので、
同じクラス内のcppを別ファイルに分けたいのですが、
可能なのでしょうか
継承を使って、10個ぐらい数珠つなぎにして、一番最後の継承クラスに関数呼び出し元の関数を書いて、
途中の継承クラスに分けたい関数を書いたら、
と考えたりしています。
40:デフォルトの名無しさん
23/05/16 15:58:56.29 mGp2Y9l5a.net
>>19
めっちゃわかります
41:デフォルトの名無しさん
23/05/16 16:03:17.10 mGp2Y9l5a.net
>>39
可能
ヘッダのクラス定義はまとめないとだめだけど
cppのソースは分かれてても最後にリンクで辻褄が合えばOK
42:デフォルトの名無しさん
23/05/16 16:24:39.60 hKNAv4Vda.net
>>39
後半で言っていることがちょっと難しいかな
多重継承の数珠繋ぎを言ってる?
よく分からんけど多分そんな変なことしなくていいよ
43:デフォルトの名無しさん
23/05/16 17:34:39.57 cdgpde7Q0.net
>>41
>>42
助かります。ありがとうございます。
勉強してみます。
44:デフォルトの名無しさん
23/05/16 21:35:23.62 +NXdN5Npd.net
可読性が悪いものは
ファイルを分けても良くはならんぞ
45:デフォルトの名無しさん
23/05/16 21:55:30.94 RFVtGrOF0.net
>>39
1つのクラスに機能を詰め込み過ぎなんじゃない?
昔、4万行のcppファイルを見たことはあるけどw
46:デフォルトの名無しさん
23/05/16 22:05:53.03 oY5Fe8SB0.net
殆どコピペなんだろうな
クラスの継承知らないヤツがよくやる荒業
47:はちみつ餃子
23/05/16 22:27:10.76 tGbGLk1R0.net
そういえば C# でクラス定義を分ける機能 (パーシャルクラス) があると聞いたことがあるけど
本来的に分けるべきクラスを見かけだけ分割するような悪い設計を誘発しそうな印象がある。
C# について全然知らんので印象だけだけど。
48:デフォルトの名無しさん
23/05/16 22:54:23.62 A1rs+At80.net
partialはXAMLから生成された.csと手書きする.csをマージするための機能なので
49:デフォルトの名無しさん (スプッッ Sd1f-zj+H)
23/05/17 07:00:26.09 s9zxu+xkd.net
>>47
多重継承っぽいやつ?
50:デフォルトの名無しさん (スップ Sd1f-kcYJ)
23/05/17 08:36:31.92 9mruUvtDd.net
分割されたそれぞれの断片をコンパイラの後工程で1クラスにまとめ上げる感じ。
なのでこんな感じの相互参照も許される。
partial class C{
private void F1(){ F2(); }
}
partial class C{
private void F2(){ F1(); }
}
まあ当然コードの見通しが悪くなるので、
コンパイラ生成が絡むとこだけをpartialにして1ファイル1クラスにしておくのが鉄則
51:デフォルトの名無しさん (スッププ Sd1f-paFp)
23/05/17 12:04:20.17 nFfh+5gid.net
「1ファイル1クラスにしておくのが鉄則」
10行のクラスも10000行のクラスも何も考えずに1ファイル
思考停止君のやること
52:デフォルトの名無しさん (オイコラミネオ MMc7-ZkZz)
23/05/17 12:36:42.78 F24a8wLtM.net
C#のpartialは基本的に自動生成されたファイルとの分離が主目的
winformsのコントロールのプロパティのイニシャライズとか人から触ってほしくないファイルで一種の馬鹿避けになってる
delphiではそのコントロール向けのファイルがバイナリでぶっ壊れてもどうにもできないし
コーディング中にコード内検索も出来ない
利便性が著しくよくない
後は一般のコードジェネレータの吐き出すファイル用にも使える
最近はmvvm toolkitで便利に使われている
コードの可読性が上がるし触られたくないものを扱うのも便利
人力コードで使う場合は長いファイルの下請けメソッドを分割する場合
単純に可読性が上がるけど普通は別のアプローチを使う
特定の機能をまとめたファイルを一つ作ってそこに関連クラスを全部入れるとかもできるけど無しだろうな
特定のタイミングでプリンターに出力するメソッドを追加してファイルのアリ無しで切り替えるとかは出来そう
53:デフォルトの名無しさん (アウアウウー Sa67-MLJk)
23/05/17 12:57:39.48 TlHThGt8a.net
おんなじ意味合いの関数なんだけどSFINAEしまくってて1000行くらいあるやつはよく見かける
54:デフォルトの名無しさん
23/05/17 13:32:11.85 6s1sKbMg0.net
時代はパーシャル
55:デフォルトの名無しさん
23/05/17 16:10:19.20 ZA2j/mjnd.net
触られたくないコードって危険を孕んで内科医?
業務の情報が1人の社員に独占されていると
そいつが急死したら詰むだろ
56:デフォルトの名無しさん
23/05/17 22:50:57.85 F24a8wLtM.net
彼も若いころは文脈も理解できてまともにコーディングできたのかもしれない
皆いつか老化して意味が取れなくなるんだから
いつか行く道と言うことで…
57:デフォルトの名無しさん
23/05/18 08:16:22.48 rquLbZPK0.net
互いに依存しないことを明確にするためにファイルを分けることはまれによくある……
static int g_foo;
class A { ... };
class B {
void bar() { baz(g_foo); A x; } // Bがg_fooやAへの依存が無いことはBをファイルを分けたらワカル分けなかったらわからん
};
58:デフォルトの名無しさん
23/05/18 08:21:13.77 rquLbZPK0.net
もっともファイルを分けたからといってもメモリのエイリアシング的な形で依存した場合は知らん
some_func()が表記上はg_fooを含まないのに実は中でg_fooのアドレスを知っていて以下略
59:デフォルトの名無しさん
23/05/18 22:15:33.79 mLb7AMe5M.net
さすがに冷たい対応だったかなと
C#でpartialが入った経緯
winformsはGUIデザイナを使ってボタン等のコントロールを自由に配置してプロパティを変えて表示される文字を変えることができる
初期はデザイナで変更するとformのファイルがそのまま変更された
そのファイルを人間も書き換えているので人がミスしたり運が悪いと整合性が取れなくなったりしてた
例えば全置換などやってデザイナの部分も書き換わったりとか
それで自動生成された部分を人が不意に触れないないようにそこだけを別ファイルに出す目的でpartial classが出来た
partial methodも作られたけど他人が使ってるのを見たことがない
60:デフォルトの名無しさん
23/05/19 02:03:23.75 iSJAQTOS0.net
日本でパーシャルと言えばパーシャル冷蔵庫
微妙に凍結させた状態にして保存するというアレ
まさにC#のpartialの事である
61:デフォルトの名無しさん
23/05/19 14:04:53.67 Y7veEz1vd.net
偏微分
62:デフォルトの名無しさん
23/05/19 14:20:06.94 s84ipUzkM.net
グラッド ダイバージェンス ローテーション
63:デフォルトの名無しさん (アウアウウー Sa2f-SwK+)
23/05/20 13:24:28.97 QfLlK72xa.net
Φ(E)
∇・E
∇×E
64:デフォルトの名無しさん (JP 0H2b-QEN2)
23/05/20 14:24:46.00 duXb8gf0H.net
ナブラッ
65:デフォルトの名無しさん (ワッチョイ 03cf-owa4)
23/05/20 14:35:25.50 mmZhl8HV0.net
チロワッ
66:デフォルトの名無しさん (オイコラミネオ MMeb-owa4)
23/05/20 15:53:45.99 KTPYLvU6M.net
APLを思い出した
さすがに使ったことはないけど
67:デフォルトの名無しさん (アウアウウー Sa2f-IRVr)
23/05/20 16:00:42.45 eGW3N412a.net
for(auto &v: createVector()) なんか処理
みたいな書き方してもcreateVectorは一回しかよばれず大丈夫ってことでいい?
68:はちみつ餃子
23/05/20 16:21:49.91 dyAKGBP20.net
>>67
せやで。
その関数が呼ばれるのは一度だけという解釈で正しい。
69:デフォルトの名無しさん
23/05/20 16:23:49.47 am3G09Kz0.net
>>67
そんくらい自分で試しなされ
$ cat test.cpp
#include <iostream>
#include <vector>
using namespace std;
auto createVector() {
cout << "hoge\n";
return vector <int> ();
}
int main () {
for(auto &v: createVector()); // なんか処理
return 0;
}
$ g++ test.cpp
$ ./a.out
hoge
70:デフォルトの名無しさん
23/05/20 18:59:35.46 VcGb9zmJ0.net
>>69
自分の環境だと通るのは知ってるけど、実は未定義でアウトみたいな場合あるから5chの有識者の意見が聞きたかった
71:デフォルトの名無しさん
23/05/20 19:26:09.53 KTPYLvU6M.net
かなり昔範囲forはプリプロセッサで展開されると聞いたことがあったなあ
そういうのから誤解なんじゃないかな
実際展開してみたけどプリプロセッサでは展開されないです
72:デフォルトの名無しさん
23/05/20 20:10:50.85 pdI1pmlS0.net
>>70
これのこと?
std::vector<int> createVector();
for(auto &v: createVector()) // セーフ
struct Result { std::vector<int> v; };
Result createResult();
for(auto &v: createResult().v) // UB
73:はちみつ餃子
23/05/21 00:13:09.51 tvaGSf6W0.net
>>71
range-based for は等価なコードを示す形で意味論が規定されてる。
URLリンク(timsong-cpp.github.io)
「こう書いた場合の挙�
74:ョと等しい」という説明が「このように展開される」と誤解されたんだろう。 コンパイラの内部で実際に展開しても構わないんだが プリプロセッサはフェイズの整合性がとれなくなるのでこの展開をプリプロセッサでは実現できない。
75:はちみつ餃子
23/05/21 00:41:25.84 tvaGSf6W0.net
一時オブジェクトの寿命は個々の具体例を網羅的に覚えるというわけにもいかんので
ちゃんと原則を理解しないといかんというのは警告しておく。
>>72 で提示された内容を解説すると、このとき createResult の結果である Result は一時オブジェクトなので
完結式の終わりには解体される。 (>>73 で提示した展開形を参照のこと。)
右辺値は参照で受けた場合に限りその参照の寿命と同じ分だけ寿命が延長されるというルールがあるので
その原則に従えば Result::v の寿命は延長されるのだが v を内包する Result が解体されるときにメンバも解体してしまうので
Result::v も無効になってしまう。
当然だがすでに解体されたオブジェクトはそのイテレータも全部が無効。
76:デフォルトの名無しさん
23/05/21 10:05:34.04 bUoMcGVnd.net
単純なFOREACHマクロだと展開できないんだよねこれ
FOREACH(T x, iterable) "文"
↓
{
auto&& range=iterable;
auto&& begin=range.begin();
auto&& end=range.end();
for(;begin!=end; ++begin){
T x=*begin;
"文"
}
}
range寿命の関係上スコープの外に漏らしてはいけない。
FOREACHの終了を表現するために"#define FOREACH_END }}"とかの間抜けなマクロが必要になる
(たぶんC++17で導入された初期化付きifを使えば誤魔化せるけど)
セパレータの":"(or ",")をプリプロセッサを見つけるのが不可能。
Tでもiterableでも":"とか","を使って表現するケースに対応し切れない
(Tにtypename std::array<int, 5>::value_type を指定されたら無理)
77:デフォルトの名無しさん (オイコラミネオ MMeb-owa4)
23/05/21 13:16:13.24 gNV32dtiM.net
そうそう
プリプロセッサは重複の無い任意の変数名を持ってこれない
固定でもスコープの問題もあるからプリプロセッサ論は馬鹿げてるなと思った
78:デフォルトの名無しさん
23/05/21 14:57:20.57 TLn2V+5X0.net
>>74
ちなみにこれはC++23からは解決する(P2644)
for文の中身のあらゆる一時オブジェクトは(謎の力によって)ループ終了まで生存するようになる
まあ現時点ではやらない方がいいし、気にしなくて良くなるまで10年はかかるだろうけど
79:デフォルトの名無しさん
23/05/21 15:50:41.28 hDRagkvp0.net
>>77
えええ!
どんな需要を満たそうとしてそんな変更するんかね?
80:デフォルトの名無しさん
23/05/21 19:09:41.96 9sSc2LHl0.net
class Foo {
int m_value;
public:
Foo() { m_value = 現在時刻に依存して決まる何かの値; }
int v() const { return m_value; }
};
int tmp;
for (i = 0; (tmp = Foo().v(), tmp < 100); i++) {
cout << i << "," << tmp << endl;
}
とかになったらどうなってしまウンダー/(;≧Д≦)\
81:デフォルトの名無しさん
23/05/21 20:47:43.16 TLn2V+5X0.net
for (auto&& x: <<ここだけだよ>>)
82:デフォルトの名無しさん (ワッチョイ 6f5f-u1DA)
23/05/21 21:41:43.50 Wy9ZySN20.net
std::for_eachと死ぬタイミング合わせようとしてるのかな
83:デフォルトの名無しさん (スププ Sdea-3V1s)
23/05/22 11:38:14.26 da9WNPSud.net
do{}while(ここにblock内で宣言した変数使えるのマダ?);
84:デフォルトの名無しさん
23/05/23 08:13:25.35 Zuh94crlM.net
Main でインスタンス化した、ファイル操作
クラスの設定を、別のクラスutilityの
インスタンスで使いたい時ってどうしたら
いいですか?
ファイル開いておいて、デバッグ内容を
そこに書き込みたい。
デバッグ終わったら不要になるんで、
あまりincludeとか変数とか増やしたくない。
VC++ のwindowsディスクトップアプリ です。
85:デフォルトの名無しさん (スップ Sd8a-Cz+X)
23/05/23 08:33:03.17 2zdXEqSEd.net
「ファイル操作クラス」ってなんのことか読み取れんが
std::osteamのことか?std::ostreamを持ってる別の仕事があるクラスか?
差し支えなければ現状のクラス定義を貼ってほしいが
86:デフォルトの名無しさん (ラクッペペ MM86-F7IQ)
23/05/23 09:15:28.22 Zuh94crlM.net
>>84
ファイル操作を含んだ、デバッグ用に用意した
クラスです。Debugクラスとします。
Debug dbg; グローバルで‥
WWinMain(){
dbg.initial(); 色んな初期設定。
dbg.filename(debugfile) ;
dbg.start(); ここで、std::ofstrm file.openしてる
dbg.writefile(“なんかかきこむ”);
Utilty utl;
dbg.closefile();
}
Class Utility{
この中で、mainの中で色々設定した内容で
(mainで用意したdbgインスタンスのまま。)
Debugクラス。使いたい。
開いたFileそのまま。。
}
こんな感じですが、伝わりますか?
87:デフォルトの名無しさん
23/05/23 10:39:56.04 X1m2WkvHa.net
Utility util(dbg);
88:デフォルトの名無しさん (ワッチョイ defb-a+t/)
23/05/23 12:30:30.59 gLCisDzi0.net
関数の命名センスが短絡的やな
扇子を磨け
89:デフォルトの名無しさん (スップ Sd8a-Cz+X)
23/05/23 12:40:55.81 2zdXEqSEd.net
std::ostreamはコピーを禁止してるから参照渡し(or ポインタ渡し)で受け取るのがいいかな
class Utility{
Debug& _debug;
public:
Utility(Debug& debug) : _debug(debug) {}
void f(){
_debug.writefile(...);
}
};
int main(){
...
Utility utl(dbg);
}
90:デフォルトの名無しさん (アウアウウー Sa2f-k5Su)
23/05/23 13:00:20.12 zQ9auONPa.net
Debugをシングルトン化しておけばいいのでは。
そうすれば、utilityもMainもDebugの定義を読むだけで、お互いに無関心でいられる。
91:デフォルトの名無しさん (スップ Sdea-9ehv)
23/05/23 13:07:36.09 Gn7U56ehd.net
staticおじさんになるんだよ
92:デフォルトの名無しさん (ワッチョイ ffda-dfFb)
23/05/23 13:19:59.30 4jUsmOvf0.net
禁じ手
グローバルおじさん
93:デフォルトの名無しさん (ワッチョイ 635f-cbOI)
23/05/23 14:52:04.84 HWUzxVfV0.net
#ifdef NDEBUG
#define DEBUG_PUTLN(line)
#else
#define DEBUG_PUTLN(line) dbg.writefile(line)
#endif
94:デフォルトの名無しさん (ワッチョイ 5f7c-aV//)
23/05/23 20:11:47.19 QG1lXeie0.net
シングルトンって実質はグローバル変数そのものなんだけどな
95:デフォルトの名無しさん (ワッチョイ dbd4-3DEL)
23/05/23 20:33:02.99 H3Kl0Etq0.net
クラス定義がそもそもグローバルだからな
96:デフォルトの名無しさん
23/05/23 23:59:19.62 4jUsmOvf0.net
int i をグローバル変数にしてたおじさん居たな
理由聞いたら書くの面倒だからとか
97:デフォルトの名無しさん
23/05/24 01:56:30.90 EzFDCa2Ya.net
全部シングルトンおじさんとglobalおじさんは一人でもいると周りがめっちゃ迷惑やな
98:デフォルトの名無しさん
23/05/24 14:31:10.50 VF8oVK+zM.net
ありがとう。
やっばり、Utility の中にも色々書く必要あり
ですね。
デバッグのためだけにUtility2 3 4全部直すのも
と思ってたけど、諦めて頑張ります。
99:デフォルトの名無しさん
23/05/24 14:34:53.03 VF8oVK+zM.net
external でインスタンス渡して、
global.h さんだけincludeしてできないかなと、
甘く考えてた時もありました。
100:デフォルトの名無しさん
23/05/24 23:58:03.92 lCJuR93r0.net
世界で1つのint iをブンブン回してるのクソワロタ
101:デフォルトの名無しさん
23/05/25 00:06:30.18 1obgfOJTa.net
ループ内でサブルーチンとか呼んだときどうするんだろう・・・
102:デフォルトの名無しさん
23/05/25 00:18:52.33 8bGOXla20.net
std::u16string_view stringView (string);
stringView = {stringView.data () + 1, stringView.size () - 1};
これの2行目はどういう意味なんでしょうか?何かの文法のような気がするのですが、調べ切れていません・・・。
103:デフォルトの名無しさん
23/05/25 00:55:03.39 NKFrr9+j0.net
グローバルなオブジェクトのコンストラクタの中からprintf()とかのC言語の標準ライブラリ機能が呼べるのはワカルが
coutとかのC++の標準ライブラリ機能は安全に呼べることは保証されるの?
104:デフォルトの名無しさん
23/05/25 01:41:17.05 WiPfB6bJ0.net
される
規格上はstdに含まれる値(オブジェクト)はユーザーコードで参照されたら(特別の規定がない限り)常に有効でなければならない
105:デフォルトの名無しさん (ワッチョイ 4aa5-owa4)
23/05/25 08:37:46.24 2LyQ/gAw0.net
>>101
rangesのviewだろ
106:はちみつ餃子
23/05/25 09:32:15.13 G3dlC7U30.net
>>101
> stringView = {stringView.data () + 1, stringView.size () - 1};
↑これは↓こう書いた場合と同じ。
stringView = std::u16string_view(stringView.data () + 1, stringView.size () - 1);
107:デフォルトの名無しさん (スップ Sdea-9ehv)
23/05/25 11:13:48.89 vvIauVZOd.net
>>105
一見意味不明何だけど何て記法?
108:デフォルトの名無しさん
23/05/25 11:49:30.93 tfjCiJA40.net
勉強中なんだけど、クラスの相互参照って気持ち悪い
109:デフォルトの名無しさん
23/05/25 12:04:14.41 tfjCiJA40.net
もう、慣れた
110:はちみつ餃子
23/05/25 12:08:58.16 G3dlC7U30.net
>>106
たぶん直接的に表す用語は定義されてないと思う。
型の情報がないときは波括弧で表されたリストは initializer_list に推論されるけど
代入のときは代入演算子のオーバーロード解決時候補に関数シグネチャとして T& operator=(T&,T); が加わるので
結果としてこのとき生成される一時オブジェクトの初期化子という解釈になる。
111:デフォルトの名無しさん
23/05/25 13:19:23.21 E3OVdEtKM.net
Uniform initialization 一様初期化とか統一初期化?
URLリンク(cpprefjp.github.io)
std::initializer_listも含んだ文法だね
std::initializer_listの方か他のコンストラクタの方になるかはけっこうルールがややこし
112:デフォルトの名無しさん (オイコラミネオ MMeb-owa4)
23/05/25 19:45:10.69 bX845kvIM.net
c++はその{}の中に書くとclassの中に書いた変数が順番に初期化される
いろいろ問題があるから他の言語で採用されていない
c++は実用面で利点があると判断されたのかそのまんま
113:デフォルトの名無しさん (オイコラミネオ MMeb-owa4)
23/05/25 19:47:55.97 bX845kvIM.net
Brace initialization
URLリンク(learn.microsoft.com)
114:デフォルトの名無しさん (ワッチョイ 1b02-XPFS)
23/05/26 06:48:21.55 kRDoXd150.net
>>105
ありがとうございます。
DTMのプラグイン(VST3)を作ってみたくて、それにはC++をある程度分かってないといけないそうなので、
参考書読んだりしているのですが、これれまでC++に全く触れてこなかったので、かなり面食らってます・・・。
サンプルのソースを見ても、いろいろな応用が含まれていて、前提となる知識がそれなりにないと分からないのかなと・・・。
115:はちみつ餃子
23/05/26 10:03:10.85 qewSmBpu0.net
>>113
C++ の仕様には未定義がたくさんあるので実際に動作させた結果から学ぶべきではないという事情がある。
ある程度は理屈で理解しておかないと簡単に破綻するよ。
実例を見ながら雰囲気で使うってのは出来ない言語だと思う。
116:デフォルトの名無しさん (ワッチョイ 67c9-HmrL)
23/05/26 10:55:39.45 Yaiov3bU0.net
しらない間に未定義踏んでて、コンパイラ変わったりしたときに挙動が変わるやつ
117:デフォルトの名無しさん
23/05/26 11:28:17.59 VVS6yE6rp.net
>ある程度は理屈で理解しておかないと
に対しての
>実際に動作させた結果から学ぶべきではない
極端じゃね?
118:デフォルトの名無しさん
23/05/26 11:37:41.87 jtoHc2Cr0.net
>>113
chatgptにサンプルコードを解説させたら?
119:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ cb3e-FIIW)
23/05/26 13:02:36.82 qewSmBpu0.net
>>116
「ちゃんとした資料を読まずに動作から何かを読み取ろうとするな」という話なので、
資料を読んだうえで手を動かして確認することまで否定してるわけじゃないよ。
少なくとも初手は入門書くらい読まんといかんという程度のことを言ってる。
120:デフォルトの名無しさん (スッップ Sdea-Q5bc)
23/05/26 21:10:27.73 u5i01UPgd.net
解脱させたらに見えたし
121:デフォルトの名無しさん (ワッチョイ 5f7c-aV//)
23/05/26 21:19:24.77 cuJor+ml0.net
「ワイのコードではこう動いてるからいいの!」「ワイが試したらこう動いたからこうなの!」
で突っ走った結果大爆発する事例が後を絶たない
122:デフォルトの名無しさん (スプッッ Sd13-Cz+X)
23/05/26 21:27:57.62 TE50P/kBd.net
未定義まで行かなくても処理系依存とか未規定動作もあるからほんとにややこしい
知らず知らずのうちにコンパイラの拡張機能使ってたりもあるし
「動けばいいんだよ!」としか考えてないとどこで足元掬われるかわからん
123:デフォルトの名無しさん (アウアウウー Sa2f-+waq)
23/05/26 22:54:23.75 C+URTl/Qa.net
んちんちんちんちんちんち
124:デフォルトの名無しさん
23/05/26 23:25:57.70 Rw5xxtFh0.net
>>120-121
そんな低レベルな奴見たことないけどな
居るには居るんだろうけど
あと逆にそういうのを「手を動かさない」「実用コードで試しもせずに机上の空論でマウント取る」ことの言い訳にしてる奴を最近よく見かけるのでな
125:デフォルトの名無しさん
23/05/26 23:42:19.49 mzi7SNrwM.net
実際VS2005ぐらいに演算の順番が決まってなくて実装依存だった
それでコードを書いてた
それがVS2007には演算順序が2005と変わってた
GCCでも別の順で計算された
どうしたらいいかわからんから多分ここに聞きにきたら未定義動作だからどうしようもない
実装依存で仕方がないと返答あり
126:デフォルトの名無しさん
23/05/27 00:10:57.47 U8Vd2x100.net
自分もVCから別環境のclangに数万行のコード移したら未定義踏んでた部分あるけど、試さずにそれを最初から予知出来てたかというと無理がある
どちらかのコンパイラのバグで通らなかったりおかしな動作する場合もあるんだし(特にテンプレート周りは多い)
書いてる最中でも疑問に思ったらすぐ調べる癖がついてりゃいいんじゃないかな
127:デフォルトの名無しさん
23/05/27 00:12:11.79 ne0x12BC0.net
>>124
128: いや、文を分けて順序付けするなり、やりようはあっただろ。
129:デフォルトの名無しさん
23/05/27 00:24:40.55 bsq21T/IM.net
>>126
上にも書かれてるけど既存のコードのどこで問題が発生してるか全てを特定できないんだよ
130:蟻人間 ◆T6xkBnTXz7B0 (スフッ Sdbf-JQ4Y)
23/05/27 00:41:28.44 LEdjjvJrd.net
最近のVisual C++なら「コード分析」機能でコードの改良点を教えてくれるかも知れない。
131:デフォルトの名無しさん (ワッチョイ 3bda-DntA)
23/05/27 00:45:08.14 JrAUAXG20.net
AIが他人が書いたクソコードのリファクタリングやってくれると助かるな
132:デフォルトの名無しさん (アウアウウー Sa8f-BLq/)
23/05/27 01:23:22.98 D5N3c6HOa.net
超すごい!人間を越えた!とかワイワイさわがしいAIだが
実際にそういう感じの「マジに困ってる、やってくれたら本気で助かる」
ような事案は結局できない、という地獄
133:デフォルトの名無しさん
23/05/27 04:58:22.78 wRHxWgs90.net
言われたとおりやるだけ、なやつの極端な例だからな
134:デフォルトの名無しさん (ワッチョイ 3bf0-TYVD)
23/05/27 08:03:41.82 hUTpNjv00.net
AIが人間並みの知性を持てば人間並みにエンバグしてくれるはず
135:デフォルトの名無しさん (アウアウウー Sa8f-BLq/)
23/05/27 08:08:34.97 ap1zYrbma.net
すごい!まさに人間そのもののAIじゃないか!
136:デフォルトの名無しさん
23/05/29 16:30:05.50 AteM0zCG0.net
責任転嫁するようになるまで人間に並んだとは認めない
137:デフォルトの名無しさん
23/05/29 17:54:13.71 I9NccWA+0.net
会社で嫌われるイヤな奴の特徴を全てプログラミングされたAIとか?
138:デフォルトの名無しさん
23/05/29 18:33:58.19 IrTtCTAo0.net
AIに相談したせいで鬱になって辞める社員が続出しそうだな
AIポイゾニングは新手のリモート攻撃として流行るかもね
139:デフォルトの名無しさん (ワッチョイ 0b6e-jMfM)
23/05/29 20:15:39.44 I9NccWA+0.net
ヘイテトリスみたいな社員AI
140:デフォルトの名無しさん
23/06/04 08:29:54.68 5jvZ+YKl0.net
質問ですがstd::stringに格納された数値文字列を数値にしたい、
しかし数値以外の文字(ただし空白文字は認める)が後ろにくっついていたらエラーにしたい、と言う場合どうす
れば良いの?
ダチャい書き方ならできうるけど人類はいつまでstrtod()や&(str[0])……
std::string str;
str ← なんか文字列入る
char* end;
double d = std::strtod(&(str[0]), &end);
if (end == &(str[0])) { エラー }
while (*end != '\0') {
if (!std::isspace(*end)) { エラー }
end++;
}
141:デフォルトの名無しさん
23/06/04 08:38:19.14 Wo5LOckB0.net
>>138 まず、こちらへ
0からの、超初心者C++相談室
スレリンク(tech板)
142:デフォルトの名無しさん (ワッチョイ 0128-w4Nq)
23/06/04 09:23:46.19 5jvZ+YKl0.net
誘導されたので誘導先に建てたはサーセン、
143:デフォルトの名無しさん
23/06/04 11:01:36.99 /SPLhkOjM.net
文字列(char配列)とstringの仕組みはダサいけど他も大体これ
さらにspanもいれる
どこも大体同じ
144:デフォルトの名無しさん
23/06/04 18:06:29.89 HhL1J/ge0.net
しかしstodの「文字列が数値で始まる場合、数値化不可能な文字があっても例外は投げずに数値化出来るところまでの部分で数値化する」ってむしろ不便だよな。
145:デフォルトの名無しさん
23/06/04 18:43:24.19 XolxJINE0.net
charに変換して文字コード比較して範囲内外�
146:ナ変換分ける処理がシンプルじゃね
147:デフォルトの名無しさん
23/06/04 18:44:47.92 XolxJINE0.net
速度気になるなら二分探索の処理に追加してやればいいし
148:デフォルトの名無しさん
23/06/04 18:45:10.55 XolxJINE0.net
再帰処理でやってもいいかな
149:デフォルトの名無しさん
23/06/04 18:45:59.18 XolxJINE0.net
順序保証したいならリンクリストもありか
150:デフォルトの名無しさん
23/06/04 18:46:48.29 XolxJINE0.net
ちんこ痒い
151:デフォルトの名無しさん
23/06/04 18:58:47.70 ym4W3arT0.net
リンクトリストな
152:デフォルトの名無しさん
23/06/04 19:08:45.19 XolxJINE0.net
内挿探索でも良さそう
153:デフォルトの名無しさん (ワッチョイ a236-OEcF)
23/06/04 20:01:40.57 0KyMklrL0.net
STLへの多重配列クラス追加まだ?
154:はちみつ餃子
23/06/04 22:37:10.94 MHoxWKtY0.net
>>142
トークナイズするときに便利。
文字列が数値表現だけになっている状態を扱うことってそんなになくない?
なんらかの文字列から取り出す操作になることは多いし、
それを前提として考えたら自然な設計だと思う。
155:デフォルトの名無しさん
23/06/04 22:54:17.16 5jvZ+YKl0.net
>>151
>なんらかの文字列から取り出す操作になることは多いし、
まさにそれやが
std::stod()ではどこまで読んだのかわからないから取り出せない……
156:はちみつ餃子
23/06/04 23:07:59.65 MHoxWKtY0.net
>>152
わかるが。
157:デフォルトの名無しさん
23/06/04 23:16:49.21 bxWaSYac0.net
仕様も確認できない奴が仕様に文句付けるとかお笑いだわ
158:デフォルトの名無しさん
23/06/04 23:21:12.95 QWRuQk/m0.net
勉強になるなぁ
boost::lexical_cast
ばっか使ってきた
159:デフォルトの名無しさん (ワッチョイ 0128-w4Nq)
23/06/05 01:56:30.15 yTJt/rkc0.net
>>154
仕様を確認して文句つけているのだから無問題
160:デフォルトの名無しさん (ワッチョイ 0128-w4Nq)
23/06/05 02:01:37.37 yTJt/rkc0.net
つか自分のスキルに合わせて仕様を変えてしまう香具師よりはマシ
161:デフォルトの名無しさん (ワッチョイ 0128-w4Nq)
23/06/05 02:39:23.25 yTJt/rkc0.net
つか初心者スレで今教えてもらったわサーセン;;;
std::stod()の第2引数でどこまで読んだのかわかるのかそうか、、、
162:デフォルトの名無しさん
23/06/05 09:40:21.73 ejs/048Ga.net
1e-3
0.4E+5
どうせ . とか + とか - とか e とか E が数字の後ろに来たらエラーにする糞オレオレ関数の出来上がり
163:デフォルトの名無しさん
23/06/05 18:46:42.35 QlKvcf+ua.net
fortran爺が1e-3を1-3と書いて送ってくるの辛い
164:デフォルトの名無しさん
23/06/05 22:24:29.81 yTJt/rkc0.net
charやwchar_tのうちは文字数くれたら別段間違うことは無いはず……
165:デフォルトの名無しさん (ワッチョイ 916e-UlWg)
23/06/06 05:24:35.89 sRXlIYgz0.net
0xe5a3ec05p-10
166:デフォルトの名無しさん
23/06/07 18:16:46.44 yJ6NJbScM.net
regex 使って、全角半角タブはreplace
しつつも、正規表現で、数字だけ残して
ってしたらいいのでは
167:デフォルトの名無しさん
23/06/07 19:51:43.45 Y1IkEaDo0.net
ファイル名で並び替えるとき数字を文字列じゃなく数として判断して並び替えるの便利だよね。StrCmpLogicalWみたいなの
168:デフォルトの名無しさん
23/06/07 20:17:49.58 Wtu+kJ5G0.net
digitntegerみたいな関数なかったっけ
javaと混同してるかもしれん
169:デフォルトの名無しさん
23/06/07 20:48:56.87 DVJV7mYE0.net
大文字小文字とか小数とか半角全角とか漢数字とかあるから闇が深い
170:デフォルトの名無しさん
23/06/07 21:25:16.49 nzVrXgF60.net
アンダーバーの位置関係も結構罠だよね
文字コード的には 大文字<アンダーバー<小文字 だから
171:デフォルトの名無しさん (オイコラミネオ MMe9-sceX)
23/06/07 23:13:43.57 ZHL7BfYmM.net
言語+コンパイラの仕様が拡張してるのにライブラリは貧弱なまま
自己流に実装してしょうもないバグが紛れ込む
関係ないけどstd::stodはC言語版と微妙に仕様が違うのだろうけどそんなの調べてない
172:デフォルトの名無しさん
23/06/08 00:14:20.61 mm4FKY9+0.net
例えばstodが解釈できる数値表現を正規表現でも解釈したいと思ったらどうしたら
173:デフォルトの名無しさん
23/06/08 11:09:51.53 rxjbLVG0a.net
仕様の不備は運用でカバー
174:デフォルトの名無しさん
23/06/09 00:34:29.94 Y9bb1A2p0.net
std::sort (std::execution::par, v.begin(), v.end());
上記で並列ソートできるとのことですが何並列なんでしょうか?
もし環境に合わせて良きに計らってくれるのなら
その良き並列数を取得する関数などありますか?
175:はちみつ餃子
23/06/09 01:32:53.73 vjFKJkM00.net
>>171
詳細は言語仕様では規定されていない。
リソースが不足していれば並列化されないこともあり得る。
並列化は大抵の場合に OS のサポートが必要だし
どういうサポートがあるかわからんので言語として明瞭な規定を決められない。
並列化される保証はないのにデータ競合が発生しないように実装するのは
プログラマの責任なので若干の理不尽さを感じなくもないが
C++ ってのはそういうもんなので……。
176:デフォルトの名無しさん
23/06/09 07:16:14.12 bBOCrSG+0.net
週末のレイトレーシングで1-17あたりをマルチスレッドにしてみたんだけど、ubuntu上でg++やインテルコンパイラだとスレッド数を増やすと逆におそくなるんです。windows上でvisualstudioでコンパイルすると、望み通りスレッド数を増やすほど速くなりました。何でなんでしょう?
177:デフォルトの名無しさん
23/06/09 08:07:59.94 e2G6/2re0.net
>>173
>週末のレイトレーシングで1-17
全く意味がわからないんだが?
>何でなんでしょう?
お前のコーティングのせいじゃないか?
178:デフォルトの名無しさん
23/06/09 08:18:32.57 m5f79nsG0.net
gccはね・・・どうも平行/並列処理には本気じゃないところがある
たとえばstd::execution::parなんか真面目にやらんかこらって言いたくなる
179:デフォルトの名無しさん
23/06/09 08:19:05.88 m5f79nsG0.net
無料なので強く出られないけどね
180:デフォルトの名無しさん
23/06/09 11:49:37.37 Y9bb1A2p0.net
皆さんレスを有り難うござます
うちはstd::execution::parで効果絶大です
$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
181:デフォルトの名無しさん
23/06/09 22:45:32.96 uysUozYZ0.net
なるほどなあ
182:デフォルトの名無しさん
23/06/10 02:07:59.33 oiDhCbH60.net
EASTLが久しぶりにバージョンアップしたね
183:デフォルトの名無しさん
23/06/10 07:02:46.03 kaZ6v5kb0.net
ほう!いいね
184:デフォルトの名無しさん (ワッチョイ b16b-q0yD)
23/06/14 07:54:14.73 /jeWb7sY0.net
time コマンドで調べたメモリの使用量 (max resident set size) が理論値よりも多くて、原因を特定するためにコード内の各箇所でその時点でのメモリ使用量を出力できたら良いなと思います。
実行環境は Linux なのですが、どのようにするべきでしょうか?
185:デフォルトの名無しさん (ワッチョイ b16b-q0yD)
23/06/14 08:43:22.06 /jeWb7sY0.net
あとメモリに関連した質問で、例えばめちゃデカい std::vector を要素数 1 に resize しても capacity はめちゃデカいままですよね?
STL コンテナ以外にも、大きいメモリが割り当てられてるオブジェクトを使用後に破棄したいというケースがよくあります。
最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが、他に、オブジェクトに割り当てられているメモリを手動で解放する方法があったら教えてください。
186:デフォルトの名無しさん (スプッッ Sd33-5Oyn)
23/06/14 08:49:33.85 Xd2fVcpxd.net
/proc/self/stat というファイルを覗きに行くか、
getrusage というシステムコールで取得することになるかな
187:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ c13e-2rqm)
23/06/14 09:19:31.16 O3itrano0.net
>>182
そのために shrink_to_fit がある。
詳細は実装依存なので何もしない関数であっても仕様に反しないけど
常識的には各実行環境で効率的に動くように実装されるので
まずは試してみても損はないと思う。
アロケータを自作してもあまり制御できないんよね。
アロケーションが必要になったらコンテナからアロケータが呼ばれるという
受動的な構造なのでコンテナによるメモリ管理戦略にそれほど関与できるわけではない。
本当にどうしても標準ライブラリの挙動の詳細が不満なら
自分で同等のものを実装する (または望ましいものをどこかから見つける) しかないよ。
188:デフォルトの名無しさん (アウアウウー Sadd-g1CP)
23/06/14 10:15:22.04 iWYHYN4ra.net
>>182
new で造って delete (または delete []) で解放
189:デフォルトの名無しさん (ワッチョイ 8bfb-Xx8j)
23/06/14 12:28:17.37 XWt8afSz0.net
更にいうと、deleteはgccでは推奨されないのでptrを使うよりはstaticもしくはvirtualを使いましょうね。
190:デフォルトの名無しさん (テテンテンテン MMeb-jufV)
23/06/14 12:29:45.65 XEzvAdInM.net
>>182
>>185とほとんど同じだけどunique ptrで管理。
ヒープの確保時間が問題になるならアロケーター使ってヒープを予約する。
191:デフォルトの名無しさん (ワッチョイ d9f0-EP1b)
23/06/14 13:12:37.90 9CAXVpD30.net
>>182
vector<空にしたいオブジェの要素の型>().swap(空にしたいオブジェ)
192:デフォルトの名無しさん (アウアウウー Sadd-g1CP)
23/06/14 13:33:02.07 iWYHYN4ra.net
>>188
vector<空にしたいオブジェの要素の型> hoge;
が既にあったとしたら
vector<空にしたいオブジェの要素の型>(hoge).swap(hoge);
で良いらしいけど副作用の心配無い?
193:デフォルトの名無しさん (ワッチョイ 219b-q0yD)
23/06/14 14:03:16.39 0kIiqVrM0.net
>>183
ありがとうございます
> getrusage
を試してみようと思います
>>185-187
STL コンテナを使うとしても自作クラスを使うとしても、オブジェクトを unique_ptr で持つことにして要らなくなったら reset() すれば確保していた分のメモリを捨てられるということでしょうか
依存関係が絡み合っていて簡単に小さいスコープに分割できないときは試してみようと思います
194:デフォルトの名無しさん (アウアウウー Sadd-g1CP)
23/06/14 14:16:54.18 iWYHYN4ra.net
reset()は違うと思う
195:デフォルトの名無しさん (ワッチョイ 01da-EP1b)
23/06/14 14:26:34.51 HNZbb8Sq0.net
>>189
その場合はメモリアクセス領域が変わるのでswapする前に取得済みだったイテレータは再取得する必要あり
196:デフォルトの名無しさん (ワッチョイ e95f-2rqm)
23/06/14 15:52:59.34 K9MvWtl90.net
>186 が何を言ってるのか意味不明でこわい。
197:デフォルトの名無しさん (ワッチョイ e95f-2rqm)
23/06/14 15:54:13.97 K9MvWtl90.net
>>191
「reset() すれば確保していた分のメモリを捨てられる」で間違いないでしょ。
198:デフォルトの名無しさん (テテンテンテン MMeb-jufV)
23/06/14 18:26:24.05 9LyNOs9uM.net
>>190
resetする必要は無いよ。
コンテナから普通に要素を削除すれば、後はコンテナクラスがよろしくやってくれる。効率は実装次第だけど。
199:デフォルトの名無しさん (ワッチョイ 219b-q0yD)
23/06/14 18:51:34.14 0kIiqVrM0.net
>>195
コンテナクラスがよろしくやってくれるのに任せるのであれば、スマートポインタで持たずに単にコンテナとして持つのと変わらないように思うのですが、違うのでしょうか。
ちゃんと理解していなかったら申し訳ありません。
200:デフォルトの名無しさん (ワッチョイ d17c-sLM4)
23/06/14 18:58:01.98 vjajEcDc0.net
vectorを信頼するなら単にclear()してshrink_to_fit()すればいい
信用できないならスマポで持っといていらなくなったら手動でブチ消せばいい
それすら信用できないならイチから自分で作れ
お前がどれだけ心配消化による
201:デフォルトの名無しさん (テテンテンテン MMeb-jufV)
23/06/14 19:18:20.42 YeSwNDrrM.net
>>196
どのコンテナを使うかによる。
vectorとかdequeはまだ確保していない要素用の領域をしばしば予約するから、>>182のような状況を回避するのは面倒臭い。
listとかmapは(これも実装次第だけど)まだ確保していない要素のための領域を予約したりしないから、他のデメリットを許容するなら>>182対策の選択肢になる可能性はある。
いずれにしても、そこまで気にするならまずベンチマークを取って実態を調査すべきだし、そもそも巨大なメモリを頻繁に確保・解放するのは設計に問題があることが多いから、メモリを解放しないで済む方法を検討してみる。
202:デフォルトの名無しさん (ワッチョイ 219b-q0yD)
23/06/15 03:20:48.20 J1cG0ikp0.net
>>198
そもそもvectorのスマートポインタ (あるいはより一般的にサイズが動的なクラスのスマートポインタ) を作り、そのvectorやクラスのサイズを変えたときって確保されてる領域のサイズも変わるんでしたっけ?
手動で変えなきゃいけないと思っていました
(また、vectorのポインタとvectorの先頭要素のポインタは意味が違うのでよりわけが分からなくなりました)
203:デフォルトの名無しさん (ワッチョイ d17c-sLM4)
23/06/15 06:50:20.05 usfnoco+0.net
std::vectorはshrink_to_fit()呼ばない限り勝手にcapacity縮めたりしないはずだけど
204:デフォルトの名無しさん (ワッチョイ d19c-jufV)
23/06/15 08:48:34.83 hMmgKiSo0.net
>>199
コンテナ内のポインタの予約は避けられないよ。
ただ、ポインタのサイズを気にするようなシビアな状況なら、そもそもc++じゃなくてcで実装することを検討すべき。
205:デフォルトの名無しさん (ワッチョイ b96e-ofsu)
23/06/15 09:00:49.34 K4jCDX8M0.net
シビアな状況でC++が使えないやつがCならOKなはずはない
206:デフォルトの名無しさん (アウアウウー Sadd-g1CP)
23/06/15 10:11:47.24 dLjlwX4ma.net
>>199
何が判ってないのかが判ってないパターンだな
まともな解答もらってても何が正しいのか(なぜ正しいのか)
すら判断出来なさそうなレベル
解答者に失礼
207:デフォルトの名無しさん (ワイーワ2 FF63-pDI4)
23/06/15 10:56:55.78 kyFBXozFF.net
他所スレで同じ様な流れが
>742
質問の仕方が悪いだけwww
欲しい情報を引き出すには一定以上の質問能力が必要
>743
質問の仕方が重要なのはその通りだけど
ここで問題にしてるのは自分が詳しくない領域では質問の仕方が悪かったかどうかも分からないってことでしょうよ
>744
>>742
質問のしかたさえ良ければ正確な情報が手に入ると思ってるのは素人だけだぞ?w
208:デフォルトの名無しさん (ワッチョイ 219b-q0yD)
23/06/15 12:02:49.40 J1cG0ikp0.net
>>201
いや、ポインタのサイズなんて全く気にしてない。
質問は、メモリの解放をコンテナに任せるならわざわざスマポで持つ意味ないよね? ってこと。
で、コンテナに任せるというのは元の質問(>>182)への回答に全くなってないよね? ってこと。
(その理由は>>184,200様の書いてくださってる通り)
つーかお前が何も分かってないのは>>195でreset()しなくて良いとかほざいてる時点でお察し。
>>203-204
笑
>>203は>>191で「reset()しなくても良い」とかほざいてて>>195と同レベ。
>>183-185,194,197,200様
ご丁寧な回答をくださりどうもありがとうございました。
勉強になります。
209:デフォルトの名無しさん (テテンテンテン MMeb-jufV)
23/06/15 12:29:34.24 QcI//Xn+M.net
>>205
コンテナのsmart ptrの扱いは調べた?
コンテナの要素とポインタの参照先の違いについて根本的な誤解がありそう。
vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
vector<smart ptr>もsmart ptr の予約はするけど、smart ptrの参照先インスタンスの予約はしない。
210:デフォルトの名無しさん (ワッチョイ 219b-q0yD)
23/06/15 13:15:56.80 J1cG0ikp0.net
>>206
だから、結局任意のコンテナ、クラスに対してスコープ内でメモリを解放する方法は?
new で生ポを持って delete するか、スマポを持って reset するかだろ?
> vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
そりゃそう。
ゆえに、メモリを間違いなくリリースしたいなら reset すればよいのですねと>>190で述べている。
それで終わりなのにお前と来たら reset は不要だの元のコンテナの挙動に任せるだの、論旨を全く理解してないとんでもレスばっかり。
> vector<smart ptr>も……
論外。
誰もスマポのvectorの話なんてしてねえ。
211:デフォルトの名無しさん (ワッチョイ 8bfb-Xx8j)
23/06/15 14:56:16.78 M9bt3STi0.net
186でも言ってるがstaticもしくはvirtualでデストラクタ使えよ
それがシンプルで高速で1行も無駄のない設計な
212:デフォルトの名無しさん (ワッチョイ 01c9-6bUV)
23/06/15 15:01:28.21 B8g22vaD0.net
182の
>最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが
がコンストラクタで確保してデストラクタで消す話というのはわかってる上で
>他に、オブジェクトに割り当てられているメモリを手動で解放する方法があったら教えてください。
なんじゃないの?
そんなものは無いっていう答えもあるにはあるけどサ
213:デフォルトの名無しさん (ワッチョイ 13f0-8sUu)
23/06/15 18:41:07.51 QIwD56Ju0.net
最近IPP触り始めたんですが全部飽和演算で面食らってます
Modulo関数は無いんですか?
214:デフォルトの名無しさん (ワッチョイ fb8c-jufV)
23/06/15 21:00:11.51 W1C5TI4i0.net
>>207
ああ、ごめん。めっちゃデカイインスタンスのvectorじゃなくて、めっちゃデカイvectorね。
それなら実装依存だけど>184か、>192とか参照無効化の制限とかコピーコストとかあるけど>189。189はsmart ptrにしとけば実用上問題ないかね。vectorのイテレーターは保存するものじゃないし。
215:デフォルトの名無しさん (ワッチョイ c14e-8sUu)
23/06/15 21:28:08.23 3cvhbwG+0.net
実際の所、vectorならclear()→shrink_to_fit()でメモリが開放されないこってありうるの?
216:デフォルトの名無しさん (ワッチョイ d17c-sLM4)
23/06/15 22:10:40.95 usfnoco+0.net
規格上はshrink_to_fit()にメモリ解放する義務はないし、実装定義で何やっても自由(capacityを増やすような真似だけは禁止)
shrink_to_fit()がなんにもしない実装でも一応規格準拠になる
そんな糞みたいな実装が実在するかは知らない
217:デフォルトの名無しさん (US 0H0b-q0yD)
23/06/16 02:13:28.00 PZdB0bgSH.net
>>211
はい結局一人だけ違う話してた
ハァァ~~~~~(クソデカため息)
218:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ c13e-2rqm)
23/06/16 11:31:25.61 QEmhRLek0.net
>>212
基本的には効率的に実装されるものだと信じて良いと思うが
どういう実装が効率的であるかは実行環境の事情による。
たとえばメモリ管理がページ単位というのは普通のことだし
その場合にページ単位より細かく確保したり解放したりしても非効率になる。
常に何もしないというような実装はあまりないと思うけど
解放するほうが非効率だと考えられる状況では
shrink_to_fit を呼んでも解放しなかったり部分的にだけ解放する
ということはそれなりにあり得そうだと思うよ。
219:デフォルトの名無しさん (ワッチョイ 01c9-6bUV)
23/06/16 12:08:14.46 nWXjt7Za0.net
capacityと OS側からみた空きメモリはまた別かもしれんわけで
アロケーターがOSからじかに要求してる場合もあれば
OSへの要求回数を減らして内部でプールしてやりくりしてるのもあるし
制御したいレイヤーによっては全部自前でやるしかない という落ちにも
220:デフォルトの名無しさん (ワッチョイ c14e-8sUu)
23/06/16 12:26:43.83 B2wRJ7jC0.net
>>215
まぁ、細かい単位のメモリだったら、実際に開放されているかどうかなんて、ほとんど動作に影響しないとも言えるしね
(未初期化変数の不具合が発覚しづらい、くらいか)
とりあえずshrink_to_fitを呼んでおいて、細かいことは気にしないのが一番かもしれないw
221:デフォルトの名無しさん (ワッチョイ 934f-q0yD)
23/06/16 12:46:08.57 H6XPX5qB0.net
「STLコンテナ以外にも」という文言が読めてない文盲さんたちがvectorの話ばっかしててワロ
222:デフォルトの名無しさん (ワッチョイ d969-2rqm)
23/06/16 15:41:25.79 KX+TErXo0.net
「STLコンテナ以外にも」はSTLコンテナも含むということ
STLコンテナの話をしても何もおかしくない
223:デフォルトの名無しさん (アウアウウー Sadd-g1CP)
23/06/16 15:43:23.81 ly+Q1cW8a.net
いつものことだが
ほんの最初の数レスで終わってるのに
どうでも良い脱線ほど盛り上がってgdgdレスでスレが延びる
224:デフォルトの名無しさん (アウアウウー Sadd-Xx8j)
23/06/16 15:46:42.75 /DJegtL/a.net
ほんそれ
回答終了してんのにちんこかゆい
225:デフォルトの名無しさん (スフッ Sd33-pDI4)
23/06/16 15:49:19.69 YNpYq5+wd.net
>>182 良く読むと
>STL コンテナ以外にも、大きいメモリが割り当てられてるオブジェクトを使用後に破棄したいというケースがよくあります。
>最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが
いやいやそもそも「関数とか局所的なスコープ(つまりautoだろ?stackだろ?)で大きいメモリ確保しようなんて思うな」って話なんだよな
226:デフォルトの名無しさん (ワッチョイ e95f-2rqm)
23/06/16 16:09:01.10 qgM8i0iT0.net
ローカルなvectorを置けばヒープ確保されるので「つまりautoだろ?stackだろ?」は
また何か誤解してる人が来たなとしか。
227:デフォルトの名無しさん (ワッチョイ 219b-q0yD)
23/06/16 16:49:22.15 ybGonaVE0.net
reset要らないとか言ってる奴らは結局何なん
228:デフォルトの名無しさん (テテンテンテン MMeb-jufV)
23/06/16 19:32:47.80 yx9ngvFiM.net
>>224
結論は>211にまとめといた。
resetは要らん。
229:デフォルトの名無しさん (ワッチョイ 92dc-gfWY)
23/06/17 08:56:51.34 3MnK6eEg0.net
>>223
「STLコンテナ以外にも」という文言が読めてない文盲さんたちがvectorの話ばっかしててωωω
230:デフォルトの名無しさん (テテンテンテン MM96-Axrn)
23/06/17 10:36:04.78 koF9X0k9M.net
>>226
「大きいメモリが割り当てられてるオブジェクトを使用後に破棄したい」なら
>185か>187。
>187はunique ptrの置き場所と解放タイミングによって解放の仕方が違って、自動変数にして関数やスコープから抜けるタイミングで解放するなら手動操作不要、vectorなどのヒープに置くとかスコープの終わり前に解放したいとかならreset()とかvectorの要素削除とかで手動解放。
いずれにしても、自動変数に巨大インスタンスを考え無しに置くのは悪手で、そのオブジェクトがスタックに巨大データを置かない(ヒープ等に置く)ことを確認してからにしたほうがいい。
231:デフォルトの名無しさん (ワッチョイ 6128-l8k0)
23/06/17 15:30:36.02 S+64vkUJ0.net
>>216
vectorのcapacityはそのvectorが氏ぬかcapacity縮小アクションが生じない限りvector固有に占有されるから
capacity(のうちsize()を超える分)と OS側からみた空きメモリはまた別でケテーイ……
一方malloc()がOSからゲットしたメモリをOSに返さずにいるのはOS側からみた空きメモリではないにしろ
同一プロセス内の他のオブジェクトの構築に使えるのだから空きメモリのうち
これすらもOSに返したいということならこの流れの中で現状答えがでていないキモヌ
232:デフォルトの名無しさん (ワッチョイ 6128-l8k0)
23/06/17 15:31:34.82 S+64vkUJ0.net
まあしいて言えばプロセスを一旦exitして再立ち上げ?
233:デフォルトの名無しさん (ワッチョイ 6128-l8k0)
23/06/17 15:45:09.56 S+64vkUJ0.net
普通に作ったら(コードで明示的に直接OSのAPIでメモリを分捕って解放とかしない限りは
プロセスのprivate bytesはプロセスが氏ぬまで増えることはあっても減ることは無いという印象、
234:デフォルトの名無しさん (ワッチョイ 7d9b-trtU)
23/06/17 16:27:35.20 5e+acAEX0.net
>>225
スマンまじで理解できないのだけど、なぜvectorに限った話をしてるの?
235:デフォルトの名無しさん (テテンテンテン MM96-Axrn)
23/06/17 19:22:00.09 mYwWSuEFM.net
>>231
巨大インスタンスは>227
236:デフォルトの名無しさん (ワッチョイ d9ab-trtU)
23/06/17 19:29:36.10 HtrmHz3i0.net
回答者のレベル低いな~~~
こんだけダラダラ続けて、結局質問者>>182が>>190で早々に結論づけてることをリピートしてるだけw
237:デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
23/06/17 19:54:50.95 9hSxsWrs0.net
アロケータ気に入らないなら自作くらいしろよポンコツ
なにもかもSTLに頼りやがってそれでPGやってるつもりになるなよ
238:デフォルトの名無しさん (ワッチョイ 6128-l8k0)
23/06/17 20:19:47.36 S+64vkUJ0.net
人類には早すぎた話題また……
239:デフォルトの名無しさん (オイコラミネオ MM91-L1I+)
23/06/17 23:14:07.63 H9lc23A5M.net
次世代の人は便利に使いこなしてるかより簡素になった仕組みを使うのだろう
240:デフォルトの名無しさん (ワッチョイ 655f-rdTE)
23/06/18 03:00:55.26 GIMFAM+a0.net
>>231
コンテナの種類を問わない一般的な方法なんてものはないからじゃないですかね
241:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/18 21:04:45.70 VwYqKwPk0.net
以下のコードでaccumulateのとこでコンパイルエラーが起こります
何故か分かります?
#include <iostream>
#include <array>
#include <deque>
#include <exception>
#include <numeric>
using Vector = std::array <double, 3>;
using Vector_Container = std::deque <Vector>;
Vector &operator += (Vector &lhs, const Vector &rhs) {
const auto size {lhs.size ()};
if (size != rhs.size ()) throw std::runtime_error ("Sizes are different.");
for (size_t i {0}; i < size; ++ i) lhs [i] += rhs [i];
return lhs;
}
Vector operator + (const Vector &lhs, const Vector &rhs) {
Vector result {lhs};
result += rhs;
return result;
}
int main () {
Vector v0 {0, 1, 2}, v1 {10, 11, 12};
Vector_Container c0 {v0, v1};
accumulate (c0.begin (), c0.end (), Vector {}); // コンパイルエラー
return 0;
}
242:デフォルトの名無しさん (ワッチョイ 515f-C6j3)
23/06/18 21:45:44.90 UCXMUPHB0.net
>>238 エラーメッセージ見ればたぶん分かる。
243:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/18 21:48:16.43 VwYqKwPk0.net
>>239
レス有難うございます
まず訂正
-accumulate
+std::accumulate
全部は貼れないですけど大事そうなところ
In file included from /usr/include/c++/12/numeric:62,
from test1.cpp:18:
/usr/include/c++/12/bits/stl_numeric.h: In instantiation of ‘constexpr _Tp std::accumulate(_InputIterator, _InputIterator, _Tp) [with _InputIterator = _Deque_iterator<array<double, 3>, array<double, 3>&, array<double, 3>*>; _Tp = array<double, 3>]’:
test1.cpp:22:14: required from here
/usr/include/c++/12/bits/stl_numeric.h:141:46: error: no match for ‘operator+’ (operand types are ‘std::remove_reference<std::array<double, 3>&>::type’ {aka ‘std::array<double, 3>’} and ‘std::array<double, 3>’)
141 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
244:デフォルトの名無しさん (ワッチョイ 9e81-L1I+)
23/06/18 23:15:51.41 w3/xAOT+0.net
ADLでoperator+が見つからないからかな?
struct Vector : std::array <double, 3> {};
みたいに定義したらいけるのでは
245:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/18 23:20:13.62 VwYqKwPk0.net
>>241
>struct Vector : std::array <double, 3> {};
>みたいに定義したらいけるのでは
通りますね
どういうこと?
246:デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
23/06/18 23:24:52.33 bX3uBTIT0.net
std::accumulateが14行目で定義したoperator+を見つけれてないのが原因っぽい。
std::accumulateの第4引数に
[](const Vector& v1, const Vector& v2){ return v1+v2;}
を追加してやるとコンパイルは通る。
14行目のoperator+をstd名前空間に入れてやれば動くにゃ動くけど色々マズいので(調査する分にはいいけど)最終的な解答にはならないかな
247:デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
23/06/18 23:29:04.68 bX3uBTIT0.net
>>242
たぶんC++コンパイラはoperator+の候補を検索するときに
Vector( = std::array<double, 3>)と同じ名前空間にあるものしか検索しない
Vectorのクラ
248:ス定義そのものがグローバル名前空間にあるなら14行目のoperator+を見つけられるけど、 今はVectorの正体はstd::array<...>なのでstd名前空間しか検索しないんだと思う
249:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/18 23:39:19.50 VwYqKwPk0.net
>>243,244
なるほど解説頂きまして有難うございます
グローバルスコープはどっからでも見えて良さそうなものの
何でグローバルスコープの関数を探さないですかね?
250:デフォルトの名無しさん (ワッチョイ a901-UvLK)
23/06/18 23:48:03.44 EGGkT3O00.net
独自のメンバ変数を持たないのなら継承してしまうのも手ではある(ただしコンストラクタやarrayを受け取るキャスト用コンストラクタとか書く必要が出ると思うけど)
ただ、そもそもカスタマイズしたり自分の用途に本当に使いやすいものを作りたいなら、ちゃんと自分で全部書いた方がいいと思うよ
251:デフォルトの名無しさん (ワッチョイ b110-lSMs)
23/06/19 00:42:02.49 2lgIrH6A0.net
>>245
std::accumlateの定義内からだと、その下の方(ユーザーコード)で定義されてるoperator+は見えてないので、グローバル名前空間の探索では見つからない
252:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/19 00:52:39.28 Q4g6N6uX0.net
>>247
std::accumlateが定義されているnumericをincludeする前に
以下のようにグローバルスコープにプロトタイプを置いても
同じようにoperator+が見えてないとエラーが出ます
using Vector = std::array <double, 3>;
Vector operator + (const Vector &lhs, const Vector &rhs);
#include <numeric>
253:デフォルトの名無しさん (ワッチョイ a901-UvLK)
23/06/19 03:40:46.00 RYn53SnN0.net
accumlateは関数テンプレートだから実体化される時点でoperator+が見えてりゃOKのはず
言われてる通りADLで対象外なのが問題
254:デフォルトの名無しさん (ワッチョイ 256b-trtU)
23/06/19 05:38:23.58 JAsvvATP0.net
>>237
(スマート)ポインタで持って要らなくなったら明示的にリリースする方法はあらゆるコンテナに対して使えるよね?笑
255:デフォルトの名無しさん (ワッチョイ f59c-Axrn)
23/06/19 08:48:03.43 KLBRX38t0.net
>>250
>>223
256:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/19 09:20:16.57 Q4g6N6uX0.net
>>249
有難うございます
グローバルスコープに定義した関数が見えないのは
どうしてなんでしょうかね?
それでは全然グローバルじゃないような気がするのですが
規格を決めるときに何か意図があったのでしょうかね?
257:デフォルトの名無しさん (ワッチョイ a901-UvLK)
23/06/19 10:39:37.41 RYn53SnN0.net
そもそもが名前空間内(よその演算子と混ざらないように)にある演算子オーバーロードを、外部からでも引数が合えば使えるように(std::operator+(a, b)とか書かないでいいように)するためのルールらしいから
外部の演算子見に行くのは�
258:レ的に合わんのじゃね std名前空間内のarrayに外部から勝手に動作を追加しようとしてるんだから、あまりよろしくないやり方しようとしてると考えた方がいい (だから>>246のように書いた、継承したら一応arrayではなくちゃんとVectorクラスに対する演算子だから通る)
259:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/19 11:53:54.08 Q4g6N6uX0.net
>>253
>std名前空間内のarrayに外部から勝手に動作を追加しようとしてるんだから、
>あまりよろしくないやり方しようとしてると考えた方がいい
なるほど
たぶんこういう考え方なんでしょうね
260:デフォルトの名無しさん (ワッチョイ 5efb-+wmN)
23/06/19 12:20:34.90 4PINPeBN0.net
つまりvector<int>を使いなさいということ
261:デフォルトの名無しさん (ワッチョイ 7d9b-trtU)
23/06/19 12:21:25.69 wGtx/iKL0.net
>>251
安価ミス
262:デフォルトの名無しさん (アウアウウー Sacd-9XmN)
23/06/20 00:04:57.81 YSi65ASja.net
実引数依存の名前探索、Argument-Dependent Lookup (ADL)は、
Koenig lookup とも言う
「Cプログラミングの落とし穴」の著者、
Koenigが、C++ に入れる事を推奨した
ADLを知っているなら、かなりのプロと言える
263:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/20 00:18:46.72 vGfe0Eju0.net
勉強になります
264:デフォルトの名無しさん (アウアウウー Sacd-9XmN)
23/06/20 02:12:24.83 1vctBLGTa.net
演算子のオーバーロードなら、フレンド関数とか?
非メンバの演算子オーバーロード | Programming Place Plus C++編【言語解説】 第35章
URLリンク(programming-place.net)
265:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/20 10:05:39.77 IIzrqfbq0.net
状況を簡略化するとこう。
namespace ns {
struct foo {};
template <class T>
void bar(const T&) {
T() + T();
} };
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
int main() { bar(ns::foo()); }
ADL は「通常の探索に加えて」関連する名前空間も探索対象にするルールなのでグローバル名前空間も探索対象になるが、通常の探索では後ろで宣言 (定義) されているものは見つけることができない。 この場合はエラーとして検出されるけど、可視な宣言と実際の定義の集合に食い違いは未定義という解釈でいいと思う。 (ちょっと自信はない……。)
だから順序を変えれば通る。
namespace ns {
struct foo{};
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo()); }
当然ながら std の (というかそれに限らず既存のライブラリの) 宣言の順序をどうこうするわけにもいかないので無理にカスタムしようとするのは筋が悪いということになる。
266:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/20 10:53:08.18 vGfe0Eju0.net
>>260
>だから順序を変えれば通る。
最近手元のg++を更新しまして10.2.1 -> 12.2.0になったんですが
前者のケースが通らなくなりまして疑問に思っていたところでした
10.2.1は寛容で両方とも通るけどC++的には後者のみ通るのが正しい?
267:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/20 11:41:30.21 IIzrqfbq0.net
>>261
前者はたぶん未定義かつ診断不要な状況なのでエラーを検出せずに通すのも正しい挙動で
プログラマがそういう状況を作ってしまうのが仕様に反する (というか結果が保証されない) という解釈になると思う。
268:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/20 13:36:04.44 vGfe0Eju0.net
なるほどー
有難うございます
269:デフォルトの名無しさん (JP 0H91-FhUT)
23/06/20 21:39:35.82 Pk8V/jejH.net
template<typename Callback>
void func(Callback cb)
{
//cb(1); // A
//cb(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
AとBをコンパイル時に呼び分けたいんですけど
どのように記述すればよいか教えていただけませんか?
270:デフォルトの名無しさん (ワッチョイ 515f-9XmN)
23/06/20 22:18:37.18 Cuq1USIJ0.net
is_invocableでおk
271:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/20 22:21:49.81 IIzrqfbq0.net
>>264
渡されたコールバック関数の引数の数によって区別するってこと?
素朴な方法だとオーバーロードするのが手っ取り早いと思う。
void func(void (*cb)(int)) {
cb(1);
}
void func(void (*cb)(int, int)) {
cb(1, 2);
}
void f1(int) {}
void f2(int, int) {}
int main() {
func(f1);
func(f2);
}
272:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/20 22:27:55.14 vGfe0Eju0.net
>>264
template<typename Callback> void func(Callback cb);
template <> void func(void (*cb) (int))
{
(*cb)(1); // A
}
template <> void func(void (*cb) (int, int))
{
(*cb)(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
273:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/20 22:29:12.98 vGfe0Eju0.net
templateが意味ないね
274:デフォルトの名無しさん (ワッチョイ 127f-L1I+)
23/06/20 22:39:00.27 ui/rWsWf0.net
265が言うようにis_invocable使うとこんな感じ?
template<typename Callback>
void func(Callback cb)
{
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
}
275:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/20 22:41:37.75 vGfe0Eju0.net
>>269
これって関係ないif節はコンパイル時に消えるの?
276:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/20 22:43:20.79 IIzrqfbq0.net
>>270
消えるよ。
277:デフォルトの名無しさん (JP 0H91-FhUT)
23/06/20 22:44:14.18 Pk8V/jejH.net
>>269
ありがとうございます。
gcc 13.1.0 でc++17でうまくいきました。
後出しで申し訳ありませんが、C++14でかけませんか?
278:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/20 22:47:27.45 vGfe0Eju0.net
>>269,271
これは知らんかった
勉強になるなぁ
279:デフォルトの名無しさん (JP 0H91-FhUT)
23/06/20 22:48:18.64 Pk8V/jejH.net
>>269
まさにこれをやりたかったです。
template<typename Callback>
void func(Callback cb)
{
// こことか
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
// ここをどうしようか悩んでいました
}
280:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/20 22:59:00.24 IIzrqfbq0.net
>>272, >>274
ひとつの関数テンプレート中でやりたいってこと?
if constexpr が導入される前だとオーバーロードなり特殊化なりで
別の関数として分離しないと書けないと思う。
is_invocable に相当するものは自分で書こうと思えば書けるが
if constexpr は言語のコアの機能だからどうにもならんし……。
281:デフォルトの名無しさん (JP 0H91-FhUT)
23/06/20 23:14:31.48 Pk8V/jejH.net
>>275
情報ありがとうございます
ご掲示いただいたコードで勉強になりました。
282:デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
23/06/20 23:42:05.71 zCL4VLm70.net
>>273
ザッツcostexprマジック
283:デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
23/06/20 23:43:57.61 zCL4VLm70.net
n抜けてたwコストがかかる演算なのは確かだけどw
constexprマジック!マジック!
284:デフォルトの名無しさん (ワッチョイ 32fb-dYQK)
23/06/21 00:07:10.76 2lh42auf0.net
C++11のSFIANE地獄へようこそ
URLリンク(wandbox.org)
template関数の実体化が1つだけ成功して、
他が失敗するように仕掛ければ呼び分けは可能。
ただ見ての通り相当面倒なことを書かなきゃならない。
285:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/21 00:28:02.40 CWKUsltc0.net
>>279
>>266と本質的に何が違うのか分からない
解説よろしく
(templateでやってることは無駄なのでは?)
286:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/21 00:41:42.51 3HBFHOpK0.net
>>280
いや、 >>279 のほうがちょっと柔軟で使いやすい。
たとえば
void f3(long int, long int) {}
みたいなのを渡したとき >>266 ではエラーになる。
引数として int を渡せる (int から暗黙に変換可能な仮引数を持っている) というのと
厳密に int そのものでなければならないというのとでは制約の厳しさが違う。
287:デフォルトの名無しさん (ワッチョイ 515f-9XmN)
23/06/21 00:42:09.27 LxMKpynY0.net
templateでやるのは質問者の与えた要件だな
宿題なんじゃね、しらんけど
288:デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
23/06/21 00:52:13.25 2lh42auf0.net
C++14にはif constexprが存在しないから
template使ったオーバーロードしか手段がない
質問者がC++14環境でって言ってたからこんなクソ面倒くさいことやれば一応できるっていう例示
289:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/21 01:17:47.52 CWKUsltc0.net
>>281,283
ありがとう
>引数として int を渡せる (int から暗黙に変換可能な仮引数を持っている) というのと
>厳密に int そのものでなければならないというのとでは制約の厳しさが違う。
こういうことね
290:デフォルトの名無しさん (ワッチョイ a901-UvLK)
23/06/21 04:29:46.61 IDPPhD2V0.net
>>260
あー本来グローバルも対象になるのか、適当こいてスマソ
だが>>248で質問者が言ってるように、元のコードで順序を変えてもダメなのよ
何故か考えてはちみつのコードを以下のようにしたら同様に通らなかった
namespace ns {
template <class T = int>
struct foo{};
// added
struct hoge{};
int operator +(const hoge &x, const hoge &y) {return 1;}
};
ns::foo<> operator+(const ns::foo<>& x, const ns::foo<>& y) { return ns::foo<>(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo<>()); }
すでに名前空間内に同名の関数があった場合はダメっぽい
291:デフォルトの名無しさん (ワッチョイ a901-UvLK)
23/06/21 09:44:10.00 IDPPhD2V0.net
あ、すまんfooがクラステンプレートになってるの直し忘れた(直しても同じだが)
292:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/21 10:22:19.76 3HBFHOpK0.net
>>285
名前探索 (name lookup) は狭い名前空間から探索していって
合致する名前があればそれより外側に同名の関数があっても
オーバーロード解決に参加しない。
わかりやすい例で言えばメンバ関数は非メンバより優先されるし、
メンバ関数内にひとつでも候補が見つかった時点で非メンバ関数は一切考慮に入らなくなる。
void foo(void) {}
struct bar {
void baz(void) {
// この foo は bar::foo のこと
// 名前が見つかった時点でそれより外の名前空間は見に行かないので
// 引数が合わなくても他の候補は試みられずエラーになる。
foo(1);
}
void foo(void) {}
};
293:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/21 10:34:08.97 3HBFHOpK0.net
例をちょっと間違えたのでやりなおし。
void foo(int) {}
struct bar {
void baz(void) {
foo(1);
}
void foo(void) {}
};
こうすると非メンバ関数の foo は候補にすらならないという話。
294:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/21 11:00:59.24 CWKUsltc0.net
g++更新にともない
自前ライブラリのビルドでエラーが出るようになって
悩んでたところを解説してくれてる
マジで凄い人達だな
295:デフォルトの名無しさん (ワッチョイ a901-UvLK)
23/06/21 11:31:26.94 IDPPhD2V0.net
>メンバ関数内にひとつでも候補が見つかった時点で非メンバ関数は一切考慮に入らなくなる。
thx。確かにこれ経験したことあるわ・・・ややこしいし名前変えて対処したけど
296:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/21 12:13:25.08 3HBFHOpK0.net
>>285 の例は using を使う形でも解決できる。 (設計意図によってはそれが妥当かどうかわからんけど。)
namespace ns {
struct foo {};
struct hoge {};
int operator+(const hoge& x, const hoge& y) { return 1; }
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
using ::operator+; // グローバルな operator+ をオーバーロード候補として参加させる
T() + T();
}
};
int main() { bar(ns::foo()); }
テンプレートを見る機会がよくあるなら std::begin を using している事例は見たことがあると思う。
297:デフォルトの名無しさん (ワッチョイ ad10-fL0y)
23/06/21 12:20:53.22 s1sJDdcu0.net
C++って、こういう悪夢みたいなテクニックで溢れかえってるよなあ
RustやらPythonだのに人気が移るわけですよ
298:デフォルトの名無しさん (テテンテンテン MM96-Axrn)
23/06/21 12:23:49.28 xjKiS8Z6M.net
記法でいうならNimがいいよ。
299:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/21 16:00:35.62 3HBFHOpK0.net
カスタマイズされた関数が呼ばれるようにする綺麗な方法として customization point object という概念が近頃は導入されてる。
綺麗な方法というか汚い部分はライブラリに隠すってだけなんだけど。
真似してみてもいいかもね。
より綺麗な方法が導入されるのはいいんだけど、
過去の方法が消えてなくなるわけでもないし完全に置き換えられるわけでもないからなぁ。
個々には良くなっても全体としては余計に複雑になるだけってのもよくある話。
URLリンク(m.xkcd.com)
300:デフォルトの名無しさん (ワッチョイ c997-trtU)
23/06/22 09:50:22.29 +UOgHQ6A0.net
max RSS (メモリ総量) の取得ってWindowsとLinuxでポータブルな方法ないの?
301:デフォルトの名無しさん (スプッッ Sd12-9xvA)
23/06/22 10:07:05.02 T+/An9G4d.net
C++標準ライブラリには無い
外部ライブラリに頼るか自分で実装するかになるけど、結局のところ#ifdefでOS依存の機能を呼び分けるしかない
302:デフォルトの名無しさん (ワッチョイ 196e-ljvc)
23/06/22 10:35:39.47 myrOOi5M0.net
std::uintptr_t get_available_memory();
とプロトタイプだけ用意して、定義を環境別に作るだな
内容的に割と単純な処理のはずで
環境別に用意といってもたいした工数にはなるめえよ
303:デフォルトの名無しさん (アウアウウー Sacd-Hkv7)
23/06/22 17:54:50.46 Sn58Ngpoa.net
Nim いいよね
C++ 嫌になったら Nim においでおいで
304:デフォルトの名無しさん (ワッチョイ c997-trtU)
23/06/23 06:00:18.48 AFPisFIg0.net
なんかのオブジェクトをポインタじゃなく実体として持ってるとして、それを delete するやり方ってないの?
たとえば std::vector A に対して
delete &A;
みたいな
305:デフォルトの名無しさん (ワッチョイ 92ad-DGQF)
23/06/23 06:14:43.58 Dz+tkRpF0.net
「実体を持っている」と言うが「誰が」持っているかにもよる
グローバル変数として宣言しているなら予めメモリ上に確保されているから破棄は無理(強引に再利用はできる)
スコープ内で変数として宣言したのなら必要なメモリはスタック上にあるからスタックを弄るしかない
別のオブジェクトのメンバ変数として宣言されているならそのオブジェクトを破棄する
306:デフォルトの名無しさん (ワッチョイ 92ad-DGQF)
23/06/23 06:17:44.59 Dz+tkRpF0.net
スコープ内でってのはローカル変数の意味で言ったの
307:デフォルトの名無しさん (ワッチョイ 3602-Ul6j)
23/06/23 07:14:23.97 GEB8UNzF0.net
A.~vector<>();でいいんじゃないの?
メモリ解放が必要ならdelete(void*)&A;とかして。
308:デフォルトの名無しさん (ワッチョイ 196e-ljvc)
23/06/23 07:18:45.05 v++V1HM40.net
>>299
deleteはdynamic storage durationのオブジェクトにのみ許される
std::vector<int> A;はautomatic storage durationの場合はその定義を囲むブレースから逸脱すれば破棄される
static storage durationの場合はプログラムの実行終了時に破棄される
thread storage durationの場合はスレッド終了時に破棄される
309:デフォルトの名無しさん (テテンテンテン MM96-Axrn)
23/06/23 07:19:36.07 pmKt7pYtM.net
極論すれば、c++の変数は自動変数しか無いから、変数で定義しているものはコンパイラに任せるしか無い。
310:デフォルトの名無しさん (ワッチョイ 196e-ljvc)
23/06/23 07:23:15.08 v++V1HM40.net
> c++の変数は自動変数しか無い
???
311:デフォルトの名無しさん (ワッチョイ adc9-1tDD)
23/06/23 08:10:40.98 Z0FiiE+w0.net
変数の生命期間よりも前に絶つのは new したものを delete する方法しかないよ
std::vector* pA = new std::vector();
std::vector& A = *pA;
:
Aで操作
:
delete pA;
この後 Aに対して操作すると鼻から悪魔
312:デフォルトの名無しさん (ワッチョイ 196e-ljvc)
23/06/23 08:36:05.01 v++V1HM40.net
auto&& A { *new std::vector<int>(0) };
delete &A;
これで「実体」のように偽装はできるけど
こんなコード書くやついたらグーパンだよ
313:デフォルトの名無しさん (ワッチョイ 92f0-L1I+)
23/06/23 08:38:29.90 OoWAXDqh0.net
このスレ読んでると目の裏がチカチカしてくるなw
314:デフォルトの名無しさん (ワッチョイ f59c-Axrn)
23/06/23 08:46:52.36 z+mnuoLR0.net
>>305
極論すれば、と言っているだろ。
せめて反例ぐらい出せよ。
315:デフォルトの名無しさん (ワッチョイ 196e-ljvc)
23/06/23 09:45:42.49 v++V1HM40.net
反例っておまえ・・・
静的変数
316:デフォルトの名無しさん (ワッチョイ 0d4e-L1I+)
23/06/23 10:11:58.67 Zb3L9Wmq0.net
>>299
deleteで何をしたいかによるな
deleteは
・デストラクタを呼び出して
・メモリを開放する
という2つの動作が含まれるが、「メモリを開放する」に関しては、確保されてもいないメモリはもちろん開放できないが、
デストラクタは実体としてはただの関数なので、普通に呼び出すことは可能
ただし、メモリが開放される(deleteされる)時にもデストラクタはもちろん呼び出されるので、2重に呼び出しても大丈夫なように設計されたクラスである必要はある
317:デフォルトの名無しさん (ワッチョイ 8101-1tDD)
23/06/23 11:56:54.20 jOpqVfQE0.net
>>299
スコープを終わらせれば消える
318:デフォルトの名無しさん (テテンテンテン MM96-UmNC)
23/06/23 13:49:52.85 RsoTpuHzM.net
Windows11でc++の開発したいんですけど開発環境何を選べばいいですか?
ちなみに趣味でおもちゃ言語のコンパイラを書こうと思います
319:デフォルトの名無しさん (スッップ Sdb2-Ul6j)
23/06/23 14:29:49.42 P5Uu3Ce/d.net
wslのclangでいいんじゃないの
320:デフォルトの名無しさん (ワッチョイ 515f-C6j3)
23/06/23 14:40:39.89 79pDbKtj0.net
>>311
> 2重に呼び出しても大丈夫なように設計されたクラスである必要はある
trivial destructor 以外は(空の ~T() {} 含め)どうがんばっても大丈夫にはならず未定義動作となる模様。
URLリンク(timsong-cpp.github.io)
321:デフォルトの名無しさん (テテンテンテン MM96-UmNC)
23/06/23 14:42:57.84 XaN8/xk5M.net
>>314
visual studioでできませんか?
visual studioに依存しないような形で
322:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/23 14:49:06.12 Xemzxb7u0.net
>>316
依存するかしないかはプログラマが気を付けることだろ
323:デフォルトの名無しさん (ワッチョイ 196e-ljvc)
23/06/23 14:58:36.88 v++V1HM40.net
>>316
つーか俺はVisual Studioを推奨する
コンパイラ本体が昔からしっかりしてるし
デバッガは無数の信者を抱えるクオリティ
324:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
23/06/23 15:11:25.32 Xemzxb7u0.net
俺はコンパイラは複数を利用するのが好ましいと思う。
気を付けてても処理系に依存している (または未定義を踏んでいる) こともある。
いくつかのコンパイラで試してみれば問題点を発見しやすい。
発現した問題についてはデバッガなりなんなりで追えばいいんだが、
問題が潜伏したまま表面に現れないってのは後になってじわじわ効いてきたりするし……。
325:デフォルトの名無しさん (アウアウウー Sacd-Hkv7)
23/06/23 16:11:46.79 lCxAQSJFa.net
>>299
デストラクタに直接リソース解放させるより
リソース解放用の dispose() みたいな関数を造っておいて
デストラクタから dispose() 呼ぶのと同時に
delete しないで dispose() だけ外から呼ぶ設計もあるよ
326:デフォルトの名無しさん (アウアウウー Sacd-Hkv7)
23/06/23 16:14:47.39 lCxAQSJFa.net
>>313
Code::Blocks (+ mingw)
327:デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
23/06/23 18:47:00.64 5tcqgCxE0.net
コンパイラの本なにがいいのかオススメ聞いたらオッサンに聞いたら怪獣が書いてある本って云われて本屋行って買ったらあとで付録のFDD誰かにかっぱわられていタコとに気付いたけどその本一冊ではなんの役にも立たないクソみたいな本だったわ
そのあとオライリーのyacc&lexの本と早乙女氏のBison&Flex本で学び直したわ