C++相談室 part166

1sage (ワッチョイ 8732-NXaD)
垢版 |
2025/04/26(土) 10:34:58.41ID:pbPDl6lv0
!extend:checked:vvvvv:1000:512
!extend:checked:vvvvv:1000:512
↑同じ内容を3行貼り付けること

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

※前スレ
C++相談室 part165
https://mevius.5ch.net/test/read.cgi/tech/1698705458/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
2025/09/26(金) 14:08:11.66ID:E9e6Z1Un0
>>679
悪い設計のせいで利用者に不自然な書き方を強いるライブラリを作ったという話だということは理解してる。
2025/09/26(金) 14:13:42.65ID:4po4sxfpp
あといちいち知ったかぶってるバカに教えてやるのも腹が立つが、普通数値演算でET使うときは代入演算子やコンストラクタに式を渡した場所で初めて式を展開するんだよ
(autoでわざと評価を遅延させることも可能だと書いただろアホ)
Eigenでも多分そう
もちろんboost::spiritとかの構文解析ならパース処理の関数に渡すまで展開しないだろうが
2025/09/26(金) 14:14:19.90ID:4po4sxfpp
>>680
不自然なのはお前の、「スキルに見合わない自尊心」だと思うぞ
2025/09/26(金) 14:24:32.42ID:4po4sxfpp
バカが屁理屈書いてきそうだから再三言うが、>>658>>657を叩くために出した問いに過ぎない
「意図しないコードになる」という話

これだからお前には絡みたくないんだよマジ鬱陶しい
2025/09/26(金) 17:03:47.95ID:iKKvsVQ80
お前ってのははちみつのこと言ってるのかね?
自分から絡んどいて何言ってんだろうコイツとしか思えんけど
2025/09/26(金) 17:53:41.26ID:uQKo8FSG0
>>684
で、>>666の導出出来ない例って何?www
2025/09/26(金) 19:18:42.84ID:+hZbpaFa0
>>685
ラムダの型導出できないだろ?
なんでこんなのも知らんのにえらそうにしてんの?
あと

https://wandbox.org/permlink/q5sTF1hp76f7jpnq

とかな
この例でfooでもif constexprを使えばautoはなくせるがそんなことやって可読性とかほざけない
他にもパターンあるぞ
謝罪してお前が作ったらしいヘボライブラリ公開したら教えてやってもいいぞ
2025/09/26(金) 19:32:01.31ID:uQKo8FSG0
屁理屈にも程がある
導出出来なきゃどうやって実体化するんだよ、Tしかテンプレートパラメータが無い状況でT以外に依存するものがあるのか?
まさか結果がTに依存するテンプレートになったら「導出出来てない」とかほざくの?
Tに依存するコンテナのイテレータと何も変わらんよそれ
2025/09/26(金) 20:12:50.41ID:uQKo8FSG0
てかその例でauto使わずに戻り値格納するのにif constexpr使うしかないと思ってるとかどんだけ経験不足なんだ・・・(はっきり処理分けする必要がある場合を除く)
そんなクソみたいな例ならさすがにdecltypeかauto使いたくなるが(そもそも使うなと言ってないんだが)、conditionalも知らんのかお前は
必死に探してきてご苦労さん
2025/09/26(金) 20:41:40.17ID:aJA0eUoF0
あの…そろそろ言っとくが

おもろいこと書いたヤツが優勝な?
2ちゃん5ちゃんの原則だぞ
2025/09/26(金) 20:46:36.85ID:uQKo8FSG0
>>665はおもろいと自分で思ってんの?w
2025/09/26(金) 20:59:48.54ID:+hZbpaFa0
>>687
おじいちゃん、ラムダの例で詰んでんのわかる?
わかんない?
わかんないかぁ
2025/09/27(土) 00:06:32.90ID:ov4hhnsF0
やっぱautoはゆるいね
C#とかPython的な感じ…
2025/09/27(土) 05:08:15.66ID:rNLW6nkI0
C++は自由なんだよ

変な風にも使えるし、傍で見てたらめちゃくちゃにもなる
2025/09/27(土) 05:36:45.87ID:p3kzti810
自分が使った方がいいと思った時は使う。
しかないよ。後は規約や上司に従うぐらいか。
2025/09/27(土) 11:22:44.98ID:0x5FUGdK0
久々にC++スレらしくなってておっちゃん楽しいよ
2025/09/27(土) 17:37:01.17ID:nSvwU9re0
>>681
コンストラクタや代入演算子で実際の計算を起動する方式も支持があるのは知ってるよ。
だからその代表例として有名どころの Eigen を話題に出したのだし、そこに齟齬はない。
その上で唯一の方式ではないし悪い設計だと言ってる。

私に反論するならどうしてそんな方式を取るのか利点 (悪い設計ではない理由) を説明すべきだった。
「数値計算で expression template を使うときは普通」なんて情報量ゼロのことを書かれても何の意味も感じられない。

コンストラクタや代入演算子をトリガーにするのは expression template を最適化として使う考え方だ。
つまり見かけ上は普通に式を書いてるだけなのに実は高速化しているというのがキモで、普通の式である「かのように」見える抽象化に意味がある。

実際の型を意識せざるを得なくなった段階で抽象化は破綻してる。
auto を使ったら何が起こるかを意識しなければならないのはライブラリ設計の失敗なんだよ。
隠れていたりいなかったりする半端な抽象化層を悪い設計と呼ぶのは間違ってるか?

> 再三言うが、>>658>>657を叩くために出した問いに過ぎない
> 「意図しないコードになる」という話

そんなので意図しないコードになってしまうような作りのライブラリは出来が悪いという話なのはかわらん。
様々な事情に配慮してそうならざるを得ないということもあるというのならわかるが、
そうじゃなくて「それが普通なんだ」と思い込んだ狭い見識での判断なんだろ?

型を書くか auto にするかはスタイルの問題で、どちらを使うかで挙動が切り替わってしまうような設計のライブラリが本当にまともか?
2025/09/27(土) 17:54:13.79ID:iipvXy1W0
よほど悔しかったんか知らんが、恥の上塗りやめたら?
autoをC++に取り込んだ人達は、お前が調子に乗るために提案したわけでも採用したわけでもなかろうよ
698デフォルトの名無しさん (アウアウウー Sacf-kv3/)
垢版 |
2025/09/27(土) 19:49:03.02ID:k7oMySGea
>>696
八光さんに同意だけど
それだとC++が設計ミスと言う結論になりかねない
2025/09/27(土) 20:00:56.28ID:nSvwU9re0
C++ が設計ミスだらけなのは今更な話だろ。
2025/09/28(日) 18:27:48.51ID:MSQtxm6D0
解決しますた!
2025/09/28(日) 19:20:47.09ID:pjQge+jC0
そうか。
2025/09/29(月) 19:03:56.70ID:ALxfRd8b0
VSCode(WSL)のclang-tidyで質問です
関数にconst付けるのを警告する「readability-make-member-function-const」って奴ですがDoSave()関数にも警告が出ます
可能ならgetterのみに付けたいのですが皆さんこれはどうされてますか?
無効にしてるか、無視してるか、const付けてるか、その他何かやってますか?

C++の環境構築は初めてなので助言をいただけるとありがたいです
よろしくお願いします
2025/09/29(月) 19:56:30.29ID:BDszbKFL0
こういうこと?
要はconst性を「セーブさせたくない」という符丁に使いたいのかな

class Hoge; // DoSave()持ち

void foo(Hoge& h1, const Hoge& ch2)
{
  h1.DoSave(); //ゆるす
  ch2.DoSave(); //ゆるさない
}

そんな変なことやめとけとしか思わないけど、どうしてもそうしたい理由があるなら言ってみ
2025/09/29(月) 20:49:50.37ID:Qgirjd9Z0
const_cast<Hoge*>(&ch2)->DoSave();
2025/09/29(月) 22:22:15.60ID:ALxfRd8b0
>> 703-704
すみませんサンプルを載せるべきでした

ソース:
double Point::X(){return x;}
void Point::X(double value){ x=value;}
ヘッダ:
static Point {
public:
double X();
void X(double value);
private :
double x=0;
};
clang-tidy を実行すると「double Point::X()」のX部分で「Method 'X' can be made const (readability-make-member-function-const)」という警告が出ます
調べてみると「constを追加して、内容が変更されないことを明確にすべき」らしいです
ソース:double Point::X() const {return x;}
ヘッダ:double X() const;

上記だけなら問題無いのですが、下記のような関数にも同じ警告が出てしまいます
ソース:void Sample::DoSave(){ ファイルの保存処理 }
ヘッダ:void DoSave();
この場合、getterではなく処理なので、const は付けるべきでは無いと考えてます

そこで質問ですが、clang-tidy で静的チェックを行う場合「readability-make-member-function-const」の扱いはどうすべきなのか気になった次第です
「無効にすればいいのか」と思いながらも、C#のプロパティではないので、「C++は変更されないことを明示した方が分かりやすいのか?」とどのように設定すべきか悩んでいます
よろしくお願いします
環境は下記:VSCode、ubuntu 22.04 (WSL)、C++ 17、clang-tidy-15
2025/09/29(月) 23:01:05.35ID:jk3QzjEU0
NOLINT
2025/09/29(月) 23:04:57.63ID:rfIMSjI90
>>705
その場合const付けたほうが良い理由は「変更されないことを明示」することより
constのインスタンスに対してその関数を呼べなくなることでは?
↓はエラーか警告(どっちかは忘れた)になると思う(constオブジェクトの非constメンバ関数は呼び出せない)

void SaveData(const Sample sample)
{
sample.DoSave();
}

void Sample::DoSave() const { ファイルの保存処理 }
にしておけば、DoSaveは呼び出せる
2025/09/30(火) 01:33:12.30ID:Xmjd+d/v0
処理だからconst付けないんじゃなくて、そのメンバ関数がPointクラスの中身を書き変えないことを保証するためにメンバ関数の後ろにconstは付ける
つまり、Save処理はPointクラスを特段変更するメソッドではないだろ?
だったらconstは付けるべき
2025/09/30(火) 07:07:46.33ID:NaKN2pJV0
>>705
つまり、constを本来の意味(中身を変更するかどうか)ではなく「getterであるかどうか」を示すラベルとして使いたいってことでしょ?
で、何を持って「getterであるかどうか」はあなたの頭の中にしかない定義であって、そのlintはもちろんコンパイラもエディタも世のライブラリも知ったことではない
それらをオレオレconstラベルに適合させるためにどうしたらいいか?というのがあなたの問うていることだ
やっぱりどうしてそんなことがしたいのか全く理解できない
2025/09/30(火) 08:58:44.76ID:0fqHawiZ0
>>705
オブジェクトがなんらかのストレージを抽象化したものであると考えたらそのオブジェクトが const であるときはセーブ機能を使えないようにしたいというのはわからんでもない。
実際の管理は他の場所でやっていて窓口に過ぎないならメンバ関数に const を付加可能 (だがそうしたくない) なこともあるだろう。

それが良い設計かどうかは脇に置いてそうすることに決めたときに clang-tidy の警告はどうすればいいのかということなら、
例外的な状況なので例外的なものとして無視してもらうしか仕方ないんじゃないか。
NOLINT コメントを書いておくと clang-tidy はその箇所については警告を抑制してくれるよ。
2025/09/30(火) 10:38:19.22ID:Dzyyn8xKd
>>706-710
御返事がおそくなりすみません
ご意見ありがとうございます
自分の理解不足と設計思想が間違ってるまたはずれてるんだと理解しました

・「readability-make-member-function-const」の指示にしたがってconstを付けるのが良い
・更に言うと-fixオプションで自動付与するレベルの内容
・だけどNOLINTで無視もできるよ(無視してるとは言ってない)

ってことで理解しました
勉強になりました
ありがとうございます
712デフォルトの名無しさん (ワッチョイ 2596-TDpG)
垢版 |
2025/09/30(火) 21:38:35.37ID:bXNPhBlr0
VC++20のテンプレート制約で不可思議なことが起きるのだけど、以下の二つは同じ意味だよね?
1だと目的通りTParentに該当static関数<T>があれば適用、なければスルーという挙動になるのだけど、
2だと無くても適用されちゃって他を探しに行かずにオーバーロード未解決に陥るんだけどどういうことだろう?

1
template<typename T, typename TParent> concept HasSizeGetter = requires { (size_t)TParent::template get_size<T>(); };
template<HasSizeGetter<TParent> T> static consteval size_t get_require_space() { return TParent::get_size<T>(); }

2
template<typename T> requires requires { (size_t)TParent::template get_size<T>(); } static consteval size_t get_size() { return TParent::get_size<T>(); }
713デフォルトの名無しさん (ワッチョイ 2596-TDpG)
垢版 |
2025/09/30(火) 21:40:50.61ID:bXNPhBlr0
ちょっと書き間違えてたけど1はget_require_spaceじゃなくてちゃんと2と同じくget_sizeね
2025/09/30(火) 23:39:48.15ID:0fqHawiZ0
>>712
オーバーロード未解決という形で現れるのはよくわからないけど
この場合はその関数テンプレートを使わなくても (呼び出さなくても) エラーになるのが正しい挙動だと思う。

get_size は依存名ではないのでテンプレートの定義時 (テンプレート実引数を当てはめる前) に名前のルックアップが試みられて失敗する。
requires 節はテンプレート引数の妥当性を検証する仕組みなのでテンプレート引数をあてはめなくても式が不成立になるようなのはエラー。

というのが私の理解なんだけどあんまり自信はない……。
2025/09/30(火) 23:47:38.26ID:0fqHawiZ0
>>714
これは TParent::get_size が存在しない場合の話で、
TParent::get_size が存在するけど TParent::get_size<T> の展開に失敗する場合はちゃんと次の候補が選ばれるはず。
(手元に MSVC がないんだけどオンラインコンパイラで一応の動作確認はした。)
2025/10/01(水) 06:54:56.10ID:O1Ml42XO0
>>715
そう、2の場合でもTParent::get_sizeはあるけど<T>とはマッチしない場合にはちゃんと1と同じ挙動になるんだよね
TParentにstaticなget_sizeが全くない場合だと1と2で挙動が変わってしまう
でも2って1をインラインに直接書いたものであって同じ意味だよね?
だからrequiresがどういう意味を持つかとか以前に挙動変わってくる時点で不可思議なんだよね
2025/10/01(水) 07:43:33.30ID:XKqCU3PC0
>>716
1 の場合は get_size は依存名だ。
そこで解釈が違うよ。
718デフォルトの名無しさん (ワッチョイ faa6-/eJP)
垢版 |
2025/10/22(水) 12:58:32.68ID:6nuMV8zc0
C++26から入るらしい^^と[::]という二つの演算子はどういう用途に使うものなのでしょうか?
2025/10/22(水) 13:31:13.53ID:/iXiQCcE0
>>718
リフレクションで検索したら色々な例がみつかるよ。
構文要素を値として取り扱う、本物のマクロだ。
2025/10/22(水) 19:35:11.69ID:t2Chdy11a
^^
↑ちょっと顔にみえる
721デフォルトの名無しさん (ワッチョイ aa71-zeRK)
垢版 |
2025/10/22(水) 21:43:50.71ID:q+0a8lK20
^^;
2025/10/22(水) 21:55:39.76ID:tW3LNod+a
^^;ゞ
2025/10/22(水) 22:05:42.67ID:b6F/3uj70
^^::←グローバル名前空間のリフレクション値
2025/10/23(木) 05:29:13.93ID:HOQCmR4+0
v^^
725デフォルトの名無しさん (ワッチョイ c1ef-6mJJ)
垢版 |
2025/10/23(木) 21:41:47.99ID:FPW1mHao0
山崎渉
726デフォルトの名無しさん (アウアウウー Sa09-6N1s)
垢版 |
2025/10/24(金) 14:17:57.63ID:nAYKU6CIa
GGは
へへ
ミミ
727デフォルトの名無しさん (JP 0Hab-oW0m)
垢版 |
2025/10/29(水) 17:48:11.20ID:KY7jGttbH
Y(^_^)Y なんすかこれ

口が違う。覚えてる人修正して
728デフォルトの名無しさん (アウアウウー Sae3-N4yN)
垢版 |
2025/11/11(火) 14:16:42.56ID:crDtfQHZa
バルタン星人のひと元気かな
2025/11/13(木) 14:20:45.09ID:jo2+4JNJM
多分基本的な質問ですまんけど、参照型のメンバー持ったクラスをmove対応させるのってどうやんのが定石?
ポインタにするしかない?
2025/11/13(木) 14:53:55.31ID:bJCWdXAy0
>>729
その参照が差す先のオブジェクトの所有権 (最終的に後始末する責任) を持っている状況ということ?
ポインタを交換する手法がよく使われるのはヌルで無効を表現してるだけなので所有権を持ってるかどうかわかるフラグを立てれるならなんでもいいよ。
型システム的に表現するなら optional と reference_wrapper を組み合わせるのがよいかな。(optional は参照を直接には保持できない。)
2025/11/13(木) 22:00:10.45ID:oKSfQs8Q0
いきなりわからんorz
2025/11/13(木) 22:38:55.22ID:PBCTneT3M
>>730
なるほどサンキュー
でもoptionは省きたいところ
moveしたあとは使わない前提でこれはUBになる?

class A {
 std::reference_wrapper<const std::string> m_s;
public:
 A(const std::string& s) : m_s(s) {}
 A(A&& rhs) : m_s(std::exchange(rhs.m_s, *(const std::string*)nullptr)) { }
};
2025/11/13(木) 22:48:43.43ID:qvmNyT2p0
・T*(ナマポ)にする
Pros: 一番素直、ムーブ後状態をぬるぽで自然に表現できる。
Cons: メンバ使ってるとこで*付けたり.を->に書き換えたりが必要。deleteとか加減算とか好き勝手できちゃう。今どきナマポとかダサい。
・std::unique_ptr<T>やstd::shared_ptr<T>にする
Cons: 多分セマンティクス違う(もともとはヨソのオブジェクト覗いてるだけでしょ?)
・std::referrence_wrapper<T>にする
Pros: 参照の置き換えという意味でこれも素直。
Cons: メンバ使ってるとこに.get()をつける書き換えが必要。ムーブがコピーになるので抜け殻に参照が残って潔癖な人だとキショい。
・std::optional<std::referrence_wrapper<T>>にする
Pros: 型的に一番真面目なので型マニアにっこり。
Cons: 書くのめんどい。「何これ?」って聞かれたときに説明めんどい(未来の自分含む)。.get()必要。
・メンバはT&のままにしてムーブコンストラクタとムーブop=の方で対応する
Pros: 既に使われてる所の書き換え不要。
Cons: ムーブ関数書くのとメンテし続けるのがめんどい。抜け殻に参照先残る。

どれも完璧じゃないから好きなの選んでいいよ
734デフォルトの名無しさん (ワッチョイ 1f01-/Hnv)
垢版 |
2025/11/13(木) 23:01:27.30ID:/tchf03X0
unique_ptrと同様のもの(unique_ref)を作ればいいんじゃねえのって話だろ
ただしptrはnullptrで無効を表現してるから
代わりにフラグを用意する
class unique_ref{
T& ref;//参照
bool isValid;//無効判定
//コンストラクタ
unique_ref(T&r):ref(r), isValid(true){}
//ムーブ コンストラクタ
unique_ref(unique_ref&& a){move(a);}
//ムーブ代入
 unique_ref& operator=(unique_ref&& a){move(a);}
move(unique_ref&&a){if(this!=&a && a.isValid) ref=a.ref; a.isValid=false;}
}
てなかんじかと
知らんけど
2025/11/13(木) 23:06:32.01ID:pKRh1I850
参照なんて引数と演算子オーバーロード以外で使ってもいいこと無くね?
2025/11/13(木) 23:07:03.58ID:qvmNyT2p0
そもそも所有権自分で保持してるメンバがもともとT&ってことはないだろ
どっか遠くのオブジェクトを見えるようにしてるだけでしょ?
(それはそれで設計的に焦げ臭いけど置いとく)
737デフォルトの名無しさん (ワッチョイ 1f01-/Hnv)
垢版 |
2025/11/13(木) 23:07:46.30ID:/tchf03X0
もしくはunique_ptrをunique_refでラップしてしまうのが楽か
738デフォルトの名無しさん (ワッチョイ 1f01-/Hnv)
垢版 |
2025/11/13(木) 23:10:58.33ID:/tchf03X0
>>736
たまにある
外部リソース(たとえばファイルハンドル)を一時的にクラスに保持して使いやすくするとか
なんにせよ寿命を明示的に管理しておかないと後でやばいことになる
2025/11/13(木) 23:14:39.55ID:qvmNyT2p0
>>738
ファイルハンドルだとして、それを管理するクラスがファイルハンドルの値自体を持たずにヨソに置いて参照するのはなぜ?
やっぱり意味がわからない
2025/11/13(木) 23:20:38.76ID:bJCWdXAy0
>>732
UB になる。
ポインタと違って参照自体は無効を表現できないのが C++ の基本ルールであり、 reference_wrapper でもそれは同じ。
それでもあえてやるなら適当にダミーのオブジェクトを作っておいてそれを参照していたら無効ということにするというようなことをできなくはないが……それはそれでちょっと不恰好だよね。
741デフォルトの名無しさん (ワッチョイ 1f01-/Hnv)
垢版 |
2025/11/13(木) 23:22:41.52ID:/tchf03X0
>>739
クラス内部でちゃんと管理するのがいいんだけど時には関数内クラスを定義してちょっとしたことを行うこともある(かも)
その時には所有権を一時的にでも委譲しなきゃならなくなる
2025/11/13(木) 23:30:06.73ID:qvmNyT2p0
>>741
ハンドルは外部で持ったままで、その関数内クラスにはハンドルの参照を渡す(関数内クラスの参照メンバを外部のハンドルで初期化する)って言ってる?それ委譲とは言わないよ
委譲したからにはそのリソースはその関数内クラスの消滅とともに消えないといけないけど、そうなったら外部で持ってたハンドルの実体はどうなるの?
どんなケースを想定してるのか全然わかんない
2025/11/14(金) 12:19:28.56ID:YW3kWFexM
>>740
までもnull objectはよく使ってるからそれにするわ
個人的にはすっきり
でもc++の参照っていらん子やん?って気がしてならない

class A {
 static constexpr std::string s_empty_str{""};
 std::reference_wrapper<const std::string> m_s;
public:
 A(const std::string& s) : m_s(s) {}
 A(A&& rhs) : m_s(std::exchange(rhs.m_s, s_empty_str)) { }
};
744デフォルトの名無しさん (ワッチョイ ff36-TpjX)
垢版 |
2025/11/14(金) 17:06:33.25ID:sw2A38eb0
>>743
型無しのnullpointerが型システム(機能保証)を破壊しているから、型を強要する参照は必要。
2025/11/14(金) 17:48:56.23ID:d/VpWy+aM
>>744
古くね?
そういうのはoptional使えってのが最近のやり方でしょ?
2025/11/14(金) 19:18:46.50ID:YeCIJNF30
>>743
参照は色々な場面で有用ではあるが、 D&E によれば最初の動機は演算子オーバーロードだと書かれている。
オブジェクトをコピーする必要がない (値をコピーせずに場所を渡せば充分) ような状況で参照がなくポインタを使うならいちいち &a+&b みたいにして書く必要が生じる。
いかにも煩わしいだろう。
2025/11/14(金) 19:55:59.90ID:p/1JbX4j0
C++より古いの新しいの含めて多くの言語が採用してるように参照は引数でのみ使用可能で良かったと思うよ
748デフォルトの名無しさん (ワッチョイ 9fda-V2U1)
垢版 |
2025/11/14(金) 20:35:30.63ID:/xnnTPah0
>>747
他の言語はともかく、C++の参照は引数に限定されてないですよ。

int a = 10;
int* pa = &a;
749デフォルトの名無しさん (ワッチョイ 1f42-q6Sd)
垢版 |
2025/11/15(土) 10:22:10.37ID:ncudN0/g0
747は、(実際の仕様はそうなっていないけど)引数でのみ使用可能なら良かったのに……という意味だと思うぞ。
750デフォルトの名無しさん (ワッチョイ 9fda-V2U1)
垢版 |
2025/11/15(土) 19:11:12.30ID:lfrbAWbT0
ああ
>使用可能で良かったと思うよ

ではなく、

>使用可能だったら良かったのにと思うよ
って事ですか
2025/11/15(土) 19:25:57.81ID:3JdS/6Ib0
カスみたいな読解力
2025/11/15(土) 19:35:13.09ID:QqRirP4Fr
そんなコミュ力高かったら、石が友達なんて言わない
753デフォルトの名無しさん (ワッチョイ 1f42-q6Sd)
垢版 |
2025/11/15(土) 19:39:44.33ID:ncudN0/g0
分かりやすいように749みたいに書いたけど、747で普通に意味が通じるので、「ではなく」というとちょっと違う気がするかな。言葉って難しい。
2025/11/16(日) 01:00:07.67ID:oagsDxeg0
こういう人が仕様書読んで実装すると思うとこわい
755デフォルトの名無しさん (アウアウウー Sa85-H7iN)
垢版 |
2025/11/16(日) 13:18:16.47ID:0LN83zrSa
横からだけど
>>747 で充分判る
>>748 は本当に日本人か?
2025/11/16(日) 13:32:50.84ID:Xh/GBEYv0
C++ばっかりやっとるからだよ
日本語を使え
757デフォルトの名無しさん (ワッチョイ 0dda-43h0)
垢版 |
2025/11/16(日) 16:38:31.73ID:r6khXsKc0
>>755
>748だけど日本人だよ。
>747日本語の文法としておかしいと思うんだが分かるんか…。
こっちが年食ったんかなぁ…。
2025/11/16(日) 16:49:19.65ID:D8AV/AUw0
あんたは機能的非識字なんでしょ
歳とか関係ないって
759デフォルトの名無しさん (ワッチョイ 91df-iLwu)
垢版 |
2025/11/16(日) 18:20:15.84ID:fnmgx6dT0
747は、日本語の文法としておかしなところは別にないけれども、748のような読み方も許すという点で多義的な文にはなっているかな。
「C++より〜ように」という前半の文脈があるので748のような受け取り方はしない方が普通だと思うが、文法的には748のような読み方も一応可能だろう。
「使用可能(ということ)で良かった」としたら、完全に一義的になっているとまでは言えないまでも、多少ニュアンスは明確になっているかな。そうでもないか。
2025/11/16(日) 19:06:28.66ID:B8gkzotY0
>>757
文字なんでニュアンスが伝わりづらいだけだよ

「この前の件だけど、両方出来るようになったよ」
「他と同じように片方のみで良かったと思うよ」

まあ誤解を与えない書き方とすると

「他と同じように片方のみで良かったのにと思うよ」
って感じで「のに」をいれた方が残念がっている様子が伝わってくるよね
761デフォルトの名無しさん (ワッチョイ e9f6-iLwu)
垢版 |
2025/11/17(月) 09:06:44.31ID:g7E0m0EQ0
C++はよく分からないので、cpprefjpにはいつもお世話になっているんだけど、生文字列リテラルのところにある「改行が入力された場合、改行の制御文字 '\n' に変換される」というのは説明として正確なのかな。
raw文字列リテラルのところの規格にはそれっぽいことは書いていないように思うし、改行文字は通常の文字としてそのままraw文字列リテラルに含められるだけであって、別に「変換」とかはされていないんじゃないかと思うんだけど。
2025/11/17(月) 10:18:46.23ID:DdlSQj440
>>761
'\n' に変換するという説明は誤りだと私も思う。
規格内の例中では \n と同等というような説明はあるのでこれを変換と誤解したのかも?
https://timsong-cpp.github.io/cppwp/n4950/lex.string#5
2025/11/17(月) 10:27:40.74ID:DdlSQj440
余談だけど生文字列リテラルの扱いにはちょっと変な特別扱いがある。
C++ では処理の初期段階で行を連結 (改行を削除) してしまうことになっていて、その時点では各改行が生文字列リテラルの中なのかどうか認識してない。
https://timsong-cpp.github.io/cppwp/n4950/lex#phases-1.2
後でトークンを分割するときになって生文字列リテラルを認識したらその範囲では連結を「取り消す」という処理が入る。
https://timsong-cpp.github.io/cppwp/n4950/lex#pptoken-3.1
結果としては改行はそのまま含まれるだけなんだけど、理屈としては色々な操作 (変換?) はされてる。

ただ、これは C++ の言語の解釈の話であって処理系の実装方法ではない。
つまり結果が同じであれば実装方法は問わないので連結してから取り消すのではなく連結の例外にしてもかまわないし、
生文字列リテラルを普通の文字列リテラルに変換するような手法もあるのかもしれない。
2025/11/17(月) 20:16:57.16ID:3c799E+W0
>>761
gccにCRLF改行のソースコードを食わせてもLF(\n)だけになったので変換はされてるんじゃないか
他のコンパイラの動作はしらね
765デフォルトの名無しさん (ワッチョイ 6e10-iLwu)
垢版 |
2025/11/18(火) 02:43:23.41ID:oTdu6LNz0
>>763
削除されるのは「\(改行)」(Pythonとかでは明示的な行継続と言われているやつ)みたいなやつだけで、(\ に後続しない)単なる改行はwhitespace文字として扱われるだけかと思っていたんだけど。

>>764
改行をLFだけにする(正規化?)のは、raw文字列リテラルに限らない共通の処理なのでは。
2025/11/18(火) 07:15:20.89ID:cPKOUaFd0
規格が決めてるのはソース中の論理的な「改行」の振る舞いであって、そのバイト表現は知ったこっちゃないって奴じゃないの
知らんけど
レスを投稿する

5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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