C++相談室 part149

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2020/02/18(火) 06:19:41.54ID:xvjipUWj
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part148
https://mevius.5ch.net/test/read.cgi/tech/1580471646/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
2020/03/03(火) 06:43:09.65ID:0/2hhSYY
>>468
例えばmemcpyの各プラットフォームごとに向けた最適化(の元のソース)はお前がここで言うようなUBだらけだろうし
boostなんかも各プラットフォーム向けに分けて書かれてる部分が多い
そこまでUBを避けてどんなプラットフォームでも動くように、なんてのもYAGNIの一種だと思うけどね
2020/03/03(火) 06:46:29.83ID:AJx5UoX4
>>470
ガチな組込みって言うか普通の企業なら開発環境も決め打ちで作ってテストする
2020/03/03(火) 06:53:54.29ID:AJx5UoX4
>>445 > それを言うなら1byte=8bitsとも限らないんで
>>447 > 1 バイトが 8 ビットじゃないアーキテクチャ (で主要 C++ コンパイラがサポートしている環境) が有るんかね?
>>471 > 数年前に触ったdspは1byte32bitだったなー

1byteは8bitと決まってるんですけど…
2020/03/03(火) 07:14:47.35ID:WkxUfZWu
え?
2020/03/03(火) 07:16:59.86ID:KvGr1Z90
なぜuint8_tを使わないの??、、
2020/03/03(火) 07:19:47.74ID:uPsaHRM9
>>475
え?
2020/03/03(火) 07:30:20.60ID:0/2hhSYY
2008年に一応はっきり決まったらしいね
ただしC++ではそうと決めてはいないので一応UB
2020/03/03(火) 07:33:02.45ID:2njekV5l
>>473
たぶん根本的なところで他人の発言が理解できてない
言いたいことはわかるけど、もはや議論になってないから黙ってろ
2020/03/03(火) 07:36:41.10ID:WsWEE8rZ
>>473
各プラットフォームに「対応」できてるなら別にいいんじゃね。
union の未定義がどうこう言ってるのは >>365 程度のことに
あえて各プラットフォームの事情を持ち込むのは割に合わない (そのくらい UB の厄介さには重みがある)
って話題だと俺は理解してる。

ターゲットが完全に固定されてたとしてもコンパイラが吐くコードを把握する自信は俺はないし
たぶん >>468 もないし、 >>473 だって出来れば避けて通りたくない?
その上でどうしてもいじらないといけないくらい速度に厳しい場面とかだったら嫌々やるかもしれないけど、
最初からはやらないって程度の話。 早すぎる最適化は諸悪の根源っていうし。
2020/03/03(火) 07:38:19.27ID:WsWEE8rZ
>>475
少なくとも C/C++ では決まってない。

>>477
対応する大きさの型の別名として定義される。
その大きさの型が存在しない場合は定義されるべきではないことになっている。
無ければコンパイルエラーになるだけなんで本当に 8bit キッカリであることが大切なら
uint8_t を使うべきだけれど、「1 バイト」という意味で uint8_t を使っちゃうと C++ の仕様に厳密な意味では
十分に汎用的であるとは言い難い。

ま、そんな環境はあんまりないんだけど組み込み環境だとたまにあるっぽい。

>>479
UB ではなく処理系定義というべき
2020/03/03(火) 07:45:28.78ID:0/2hhSYY
>>480-481
あのさ、一応UBってことはすぐ指摘されて本人もわかってんだよ、質問者もとっくに見てるはず
>>407辺りから意味無くマウント取るような言い方する奴(はちみつ含む)が出たから荒れてんだろ
そこまで言うなら今現在存在する環境でunionによるtype punningが出来ない環境を挙げてみろ
おそらくどこかにはあるんだろうが、1byte=8bitでない環境はすでに挙げられてるのにunionの方は全く例が出て来ない
>>480
理解出来てないのはお前だ
2020/03/03(火) 07:47:02.82ID:AJx5UoX4
>>482
> 少なくとも C/C++ では決まってない。
決まっていないという根拠よろしく
2020/03/03(火) 07:50:44.52ID:0/2hhSYY
>>484
自分で調べろ
2020/03/03(火) 08:03:53.36ID:NOkKAnZ5
>>483
UBだってことは分かってる、ぼくは>>407でカチンときて怒ってるだけだ、ってことだろ。もうただの口喧嘩でこれ以上何も議論することは無いんだからさっさと終わりにしなよ。
2020/03/03(火) 08:07:38.96ID:0/2hhSYY
お前もたいがい煽ってると思うが

>終わりにしなよ
俺に言うなよ
2020/03/03(火) 08:22:51.66ID:AJx5UoX4
>>485
傍から低能丸出しのレスかよ…
何を馬鹿にしてるのかもわかってないだろw
2020/03/03(火) 08:23:01.86ID:Pp/8GnxB
>>483
> そこまで言うなら今現在存在する環境でunionによるtype punningが出来ない環境を挙げてみろ

↓こういう例は把握してるの? >>405 みたいな理解だとこんなコードもエイリアス有効という話になっちゃいそうで危ないと思う。
https://wandbox.org/permlink/qrUVwDZbNPRnOQyN

#include <stdio.h>
#include <stdint.h>
int f(uint16_t* u16, uint32_t* u32) { *u16 = 0x1111; *u32 = 0x22222222; return *u16 + *u32; }
union U { uint16_t u16; uint32_t u32; };
int main() { union U u; printf("%08x\n", f(&u.u16, &u.u32)); }

出力 (gcc 9.2.0 -O2):
22223333
2020/03/03(火) 08:31:00.08ID:WsWEE8rZ
>>483
実際に有るか無いかなんて知らんよ。
俺は検証するのが割に合わんから可能なら避けるし、 >>365 程度のことに「あえて」使いたいという気持ちはわからんと言ってる。

俺は何がなんでも UB は絶対にダメなんてことは書いてないし、十分に検証できてるものにまで文句は付けんよ。
2020/03/03(火) 08:45:51.11ID:WsWEE8rZ
>>484
- std::uint8_t は cstdint にある。 (C++17 の 21.4.1)
- cstdint は C 標準ライブラリヘッダの stdint.h と同じように全ての型とマクロを定義する (同上)
- C++17 が参照する C の規格とは C11 (ISO/IEC 9899:2011) である (C++17 の 2)
- uintN_t はオプショナルだが 8, 16, 32, 64 については対応する型が存在するなら提供しなければならない (C11 の 7.20.1.1)
- char が 8bit ならば C++ には uint8_t は必ず存在するはずだがオプショナルであると言ってるから 8bit の型がない (char が 8bit ではない) ことは想定内なんだろう

というのが根拠。
2020/03/03(火) 08:49:11.40ID:87wKGSsV
いわゆる「悪魔の証明」ですか。
2020/03/03(火) 08:50:30.01ID:0/2hhSYY
>>489
strict aliasing rulesに対する違反にまで話広げてるんだろうけど
さすがにそこまで擁護する気は無いし自己責任じゃないの
そこまで悪質なコードになると話違ってくる

>>490
いやいや、一般的な環境で>>396みたいなのは検証するまでもないから
だいたい昔は未定義だったのが最近の仕様で変わったのもあるだろ
2020/03/03(火) 09:13:15.69ID:WsWEE8rZ
>>493
検証するまでもないという確信を持てる程度に (その現場か個人の経験として) 実績があるってことでしょ。
本当に何もないところで確信を持ってるんだったらそれはそれで駄目だと思う。
2020/03/03(火) 10:05:21.19ID:dPHWJmki
>>467
> どうせunion使わないためにポインタのキャストとかだろくっだらねえ

アウト
なぜunion使うかの前提すら理解してない
2020/03/03(火) 10:41:55.49ID:Zi2Vm8jS
>>472
必要ないファイルを削ったら3MBになった。ありがとう。
2020/03/03(火) 10:43:38.18ID:0/2hhSYY
ちなみに>>489の例はunionじゃなくて同じ変数を指すポインタ渡しても同じことになるからね
2020/03/03(火) 11:04:57.92ID:4ZFJ43jO
>>483
> そこまで言うなら今現在存在する環境でunionによるtype punningが出来ない環境を挙げてみろ

今時点では知らないしないだろうな
でも今後もそうなのかはわからない

1byteの定義なんかは処理系がターゲットcpuごとに決めるもの
エンディアンとかも
これは問題視されない

unionに関しては、そういう類いではないだろう
理由は把握してないけど、非podの場合を含めて意味論が決められない、
あるいはaliasingに関係して明確に使うなということなのかもしれない

あえてcと非互換にしているわけで、グレーであることは知っておくべき

ちなみに20からpodという文言が消えると聞いた
さらにcとの乖離が進むのかもしれない
2020/03/03(火) 12:22:06.47ID:AJx5UoX4
>>491
で、そのどこにバイトの話があるんだ?
2020/03/03(火) 12:36:13.65ID:4ZFJ43jO
CHAR_BITS の定義でしょ
自分で確認しろ
2020/03/03(火) 12:40:22.22ID:ctFzSosi
POD=trivial&&standard-layout
ってC++11の時に整理済みでしょ
概念は消えないよ
2020/03/03(火) 12:52:22.33ID:GzyUVdF6
>>489
それはgccのバグに思える。
2020/03/03(火) 12:59:47.46ID:0/2hhSYY
バグじゃないぞ
これがバグだったら最適化にかなりの制限がかかってしまう
strict aliasing ruleでググれ
2020/03/03(火) 13:01:57.30ID:GzyUVdF6
>>503
最適化しない場合とした場合とで結果が変わってくるのは駄目な最適化。
2020/03/03(火) 13:04:15.59ID:0/2hhSYY
だからググれって
鬼の首を取ったかのように叩く奴が出てくる前に教えてやってんのにw
2020/03/03(火) 13:05:53.55ID:WsWEE8rZ
>>499
肝心なことが漏れてた。 すまぬ。

C++17 だと 4.4 の脚注に

> The number of bits in a byte is reported by the macro CHAR_BIT in the header <climits>

とあって、バイトとは char の大きさのことだというのが C++ での考え方だと思っていい。

C11 だと 5.2.4.2.1 の CHAR_BIT の説明のところに

> Their implementation-defined values shall be equal or greater in agnitude
> (absolute value) to those shown, with the same sign.
>
> - number of bits for smallest object that is not a bit-field (byte)
> CHAR_BIT 8

という言い回しがあって、 CHAR_BIT は 8 以上であればいい (8 キッカリとは限らない) と解釈できる。
それと、ポインタを持てる単位がバイトだということが示唆されているとも言える。
2020/03/03(火) 13:08:55.41ID:GzyUVdF6
>>491
charのbit数は決まってないが、バイトはコンピュータ用語として8バイトと決まっているはず。
2020/03/03(火) 13:10:50.46ID:GzyUVdF6
>>506
多分、
「The number of bits in a byte is reported by the macro CHAR_BIT in the header <climits>」
は、書き間違いで、正しくは、
The number of bits in a char is reported by the macro CHAR_BIT in the header <climits>
だと思われる。
2020/03/03(火) 13:17:56.62ID:GzyUVdF6
>>507
そうか、歴史的には、byteが7bitだったこともあったんだね。
2020/03/03(火) 13:32:49.23ID:WsWEE8rZ
>>507
これな。
https://ja.wikipedia.org/wiki/IEC_80000-13
C++ が参照規格として示してないので採用してないんでしょ。

まあそんなこと言ったら英単語の意味だってどうとでもとりようがあったりするからアレだけど、
あらためて C++ の規格の中でバイトについて書いてある以上は C++ 世界では
「コンピュータ用語としてのバイト」を採用してないと解釈するのが自然。

将来的には変更されることもあるかもしれんけども。

>>508
C++20 のドラフトでもそのままなので本気で間違ってると思うなら指摘してあげればいいんじゃね?

>>509
9bit のマシンもあったらしいよ。
https://ja.wikipedia.org/wiki/ACOS-6
2020/03/03(火) 13:48:53.72ID:4ZFJ43jO
>>501
概念消えるとは言ってないけど
今回文言消す理由ってなんなの?
何も知らずに口挟むとは思えないから質問させてくれ
2020/03/03(火) 14:19:12.58ID:WsWEE8rZ
>>511
もう POD という区分が適切な場面はあんまりないから、という意味のことが書いてあるっぽい。
https://botondballo.wordpress.com/2017/11/20/trip-report-c-standards-meeting-in-albuquerque-november-2017/
2020/03/03(火) 14:41:53.95ID:ctFzSosi
trivialは生成解体の話で、standard-layoutはデータ配置の話だから
PODってのはレイヤーの違う性質が混ざってて規格に使う用語としては筋悪なんですわ
2020/03/03(火) 16:26:35.30ID:GzyUVdF6
>>510
>C++20 のドラフトでもそのままなので本気で間違ってると思うなら指摘してあげればいいんじゃね?
annotated C++ reference manual, 3.2.1c Integral Limits には、
CHAR_BIT   8  maximum bits in a byte
とあった。
2020/03/03(火) 16:39:36.38ID:GzyUVdF6
>>514
ANSI/ISO, Standard C プログラマーズ リファレンス
P.J. Plauger / Jim Brodie, 日本語訳, ASCII

第一部 第一章 基本整数型 には、
--------------------------------------------------------
表記,     最小範囲,  表現における制限
--------------------------------------------------------
char,     [0,128),  signed char か unsigned char のどちらかと等しい。
signed char, (-128,128), 少なくとも 8bit 精度の符号付整数
unsigned char, [0, 256), signed charと同じサイズ。負の数は無い。
--------------------------------------------------------

第二部 第二章 標準ヘッダ <limit.h> には、
--------------------------------------------------------
CHAR_BIT
#define CHAR_BIT <#if 式 ≧ 8>
このマクロは、char 型のデータオブジェクトを表現するのに使われているビット数の最大値と置き換わる。
--------------------------------------------------------
とある。

後半は >>514 とは異なり、byte ではなく、char となっている。
2020/03/03(火) 16:46:23.12ID:GzyUVdF6
type punning について、このスレで議論されていた union の場合は、「適合コード」の例とされている:

https://www.jpcert.or.jp/m/sc-rules/c-exp39-c.html

適合コード
以下のコード例では、オブジェクトの有効な型と互換性のある型を持つ union 型を使用している。

union {
short a[2];
int i;
} u;

u.a[0]=0x1111;
u.a[1]=0x1111;

u.i = 0x22222222;

printf("%x %x\n", u.a[0], u.a[1]);
このコード例では確実に "2222 2222" と出力される。
2020/03/03(火) 16:56:05.32ID:GzyUVdF6
union による type punning は、C99やC11では大丈夫になったのではないか。
最後に代入したメンバ以外のメンバからの読み出しは、合法になったようだが。
よく読んでないので分からん:

https://stackoverflow.com/questions/11639947/is-type-punning-through-a-union-unspecified-in-c99-and-has-it-become-specified
2020/03/03(火) 16:58:14.25ID:GzyUVdF6
>>517
Finally, one of the changes from C90 to C99 was to remove any restriction on accessing one member of a union when the last store was to a different one.
The rationale was that the behaviour would then depend on the representations of the values.
Since this point is often misunderstood, it might well be worth making it clear in the Standard.

[...]

To address the issue about "type punning", attach a new footnote 78a to the words "named member" in 6.5.2.3#3: 78a
If the member used to access the contents of a union object is not the same as the member last used to store a value in the object,
the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning").
This might be a trap representation.
2020/03/03(火) 20:10:58.79ID:6u3PFyGZ
>>515
日本語訳が間違ってる可能性もあるな
2020/03/03(火) 21:25:40.77ID:s8qGwiQH
>>514
頑なに仕様書読まないのはなぜなのか
2020/03/03(火) 22:12:33.33ID:WsWEE8rZ
>>520
仕様書が間違ってると思ってる (>>508) からじゃね。
2020/03/04(水) 00:45:53.15ID:And/nx/1
C++は間違っているからな
間違いで間違いを正すことはできな
2020/03/04(水) 01:36:12.37ID:tHLmVZnX
>>515 も仕様書だと思うのだが。
2020/03/04(水) 08:18:37.27ID:wOgWtFGu
それに基づいて作られた製品があればの話だな
2020/03/04(水) 09:01:59.59ID:obnoKtcJ
まあc++の仕様を完全に守ってる実装なんて一つもないしな。
それ確かめるのに工数かかるってどうなん?とは思う。
2020/03/04(水) 09:56:46.98ID:0Mjry1zX
>>523
それは解説書
2020/03/04(水) 10:55:23.42ID:wOgWtFGu
仕様を説明していても仕様書かどうかとは別な話だな
2020/03/04(水) 12:41:56.62ID:tHLmVZnX
>>526
実際には、あれは普通の解説書ではなく、コンパイラを実装する人が重宝するようなバッカス記法や決定性オートマトンなどを使って仕様がかなり厳密に書かれた特殊な本。
2020/03/04(水) 13:50:02.87ID:BrIasXcf
>>515
古い C では違ったのかもしれないと思って
念のために C89 も確認してみたけどそのときから >>506 と同じ文言になってるぞ。
C (の公式な仕様) では最初からバイトとは char の大きさのことと結論していい。

K&R 第二版の日本語訳の付録Bだとバイトとは書いていない。
あくまでも要約だから省略したのかもしれないし、
前書きには「予備版 (ドラフトのこと?) が出ていたので早く出せた」という意味のことが書いてあるので、
仕様の決定稿が出る前の一時期にはバイトとは記述してなかった (それを元に本にした) 可能性はあるのかもね。
2020/03/04(水) 13:54:01.41ID:BrIasXcf
C/C++ の仕様が信用ならんなと思うのは欠陥報告 (Defect Report) の存在だな。
仕様書に書いてないことの確認がとれていても仕様にないとは言い切れない。
把握できるわけないだろ!
2020/03/04(水) 14:10:16.09ID:wOgWtFGu
公文書だかんな
はい発表しましたよ、周知義務よろしく

こういう体質なのは今さら驚いても始まらん
2020/03/04(水) 14:57:19.24ID:BrIasXcf
公文書なら著作権法による保護が及ばないのでそれはそれで利点があるんだけどな。

実際には ISO は民間組織だし、正式な規格票はクソ高価すぎる。
私はドラフトと cpprefjp しか見てないんだけど、買った人いる?
2020/03/04(水) 16:25:27.01ID:tHLmVZnX
VS2019 の limits.h のコメントはこうなっている :
#define CHAR_BIT 8 // number of bits in a char
2020/03/04(水) 16:43:02.53ID:BrIasXcf
そうか。
2020/03/04(水) 16:43:03.91ID:CqUkRGBA
VSの想定環境では正しいし何の問題もないな
2020/03/04(水) 16:58:40.94ID:tHLmVZnX
CHAR_BIT なのに本当に「number of bits in a byte」が厳密定義なら、何らかの説明が欲しい所ではある。

ただ、C言語では、charは言語が扱える整数の「最小単位(?)」などと書かれている文書を見たことがある。
だとすれば、Cに高級アセンブラの地位を期待する需要が有る以上、charのbit数がbyteと一致する必要は必ずあるとは思う。
総合的に考えれば、C言語においては、char=byte でなくてはならず、もはやbyteも絶対に8BITでなければならないので
char、byteがいずれも8bit
であることは事実上、必須である。
537デフォルトの名無しさん
垢版 |
2020/03/04(水) 17:05:12.53ID:tHLmVZnX
Wikipediaの「整数型」のところで、C言語では、何があろうとsizeof(char)は必ず1になると決められており、たとえ16BITワード単位のアーキテクチャでも、CHAR_BIT は 16になるが、sizeof(char)は必ず1になるのだそうだ。
一方、sizeof(X)は、Xの「バイト数」だとされているわけだけど、はっきりいってこんな状況では総合的に考えて、charを8BIT以外には出来ない。
2020/03/04(水) 17:14:44.63ID:BrIasXcf
>>536
Rationale の 6.5.3.4 に記述がある。
http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

sizeof(char) は 1 を返す。
たとえこの単位が 36bit 幅であっても。
C 用語の「バイト」はストレージの最小単位であることを意味する。
2020/03/04(水) 17:16:32.37ID:tHLmVZnX
>>536
>C言語では、charは言語が扱える整数の「最小単位(?)」
は、>>506 の以下の部分にも書いてあるようだ。
CHAR_BIT とは、
「bit-field以外で最小のオブジェクトのbit数(byte)」
だと:

>C11 だと 5.2.4.2.1 の CHAR_BIT の説明のところに
>> - number of bits for smallest object that is not a bit-field (byte)
2020/03/04(水) 17:18:06.36ID:BrIasXcf
ポインタを作れる単位を最小単位にするのは理に適ってるんじゃないの。
2020/03/04(水) 17:20:06.24ID:tHLmVZnX
「bit-field以外のオブジェクトの最小単位」
なわけだから、ポインタが指しうるアドレスの最小単位でもあるわけだ。
言葉が変かも知れないが。
2020/03/04(水) 17:35:08.28ID:obnoKtcJ
気にするような環境にない奴に限ってこういうこと気にするのな。
2020/03/04(水) 17:39:54.09ID:tHLmVZnX
個人的には、ソース配布してダウンロードした人が各自勝手にコンパイルするようにするようなプログラムを書いたことが無い。
必ずバイナリレベルでテストして十分デバッグ済みだと思ってからバイナリを配布してきたから。
ソース配布文化は別世界。
2020/03/04(水) 18:59:40.00ID:Py0/41jA
だから何だ
結局何が言いたいんだ
規格が間違ってるって言うならISOのWGに意見書出せよ
情報は歓迎だぞ
2020/03/04(水) 20:23:54.51ID:3yz+4Wbb
>>537
byteは16bitになる可能性を自分で示しているじゃないか。
一体何と矛盾してるんだ?
2020/03/04(水) 20:40:21.43ID:+mh63BBw
まず一生触ることのない環境のことはどうでもいい
2020/03/04(水) 20:47:19.33ID:wOgWtFGu
お、江添きたか
2020/03/04(水) 21:36:25.82ID:9NgWGcWV
>>536
C,C++ はそれぞれずっと前から "byte" を独自定義していて、 2008 年発行の IEC 80000-13 の定義は関係ないんだよ。
(・・・って >507 に書いてあったわ。なんでまだこんなこと言ってるのこの人?)
2020/03/04(水) 22:55:14.08ID:InlLUMV0
byteが何者かわからんから、オクテットとか言う呼び方があるのだろう
2020/03/04(水) 22:56:33.25ID:wOgWtFGu
nibble != 4bits ということはあるのかね
2020/03/04(水) 23:02:36.78ID:BrIasXcf
>>550
どこかに正式な定義があるかはわからんけど、
Byte の語源は Bite (噛みつく) らしいし、
それよりは控えめってニュアンスは感じるよね。
2020/03/05(木) 08:23:20.57ID:Hv5fT+Tn
c++初心者です
実際現場でよく使われる関数はどんなものがありますか?
2020/03/05(木) 08:31:27.44ID:eBZoUINk
begin, end, operator ++, operator !=
2020/03/05(木) 08:48:57.01ID:maJEmc7K
>>553はSTLしか使ったことないアマチュアの発言
2020/03/05(木) 09:32:08.09ID:eBZoUINk
STLだと? 俺はrange-based-forを想定して書いたんだが、気が付かなかったのか?
2020/03/05(木) 09:35:26.73ID:oibZ2+F1
一緒だよ
557デフォルトの名無しさん
垢版 |
2020/03/05(木) 09:44:32.03ID:tzyiEzvg
c++11でregexの正規表現で\sと\Sがエラーになるけど、
全部自分で記述で[ \t\r\n]とかしないといけないですかね?
2020/03/05(木) 10:06:12.56ID:HyVcGvBE
>>552
関数セットとしては、やはり伝統的なCのものを使うことが多いんではなかろうか。
ソートや乱数、最大最小値計算、正規表現なんかはC++風のものが好まれる傾向が出始めてるかもしれない。
文字列の一致テストなども、個人的にはCのstrcmp()、_strcmpi()、strncmp()、memcmp() なども結構使ってるけど、若い人の間では std::string の比較機能が好まれているかもしれない。
というかC++から勉強した場合、それしか知らないだけかも知れないが。
文字列表示は、ネットではなぜか cout 系で、cout << "Hello"; のようなものを良くかけるが、
表示する際の16進数と10進数の区別や、表示桁数の指定、float/double値の有効数字桁数の指定、先頭に0を付けるかどうかなどを指定し易いので、古いと言われようが個人的には昔ながらのprintf()が好きだ。
559デフォルトの名無しさん
垢版 |
2020/03/05(木) 10:22:38.04ID:TYdcXopQ
マニピュレータを作ることが出来るのでストリームを使ってるだけでは。
560デフォルトの名無しさん
垢版 |
2020/03/05(木) 10:23:41.63ID:TYdcXopQ
若い子は馬鹿なのでストリームを好むキリッって風に見えるのだろか。
2020/03/05(木) 10:59:35.38ID:HyVcGvBE
C++の文字列比較で比較開始位置や最大長さを指定したい場合、
if ( str1.compare(0, 5, "abcdefghijklmn") == 0 )
のように書く必要があるが、Cのstrncmp()だと
if ( strncmp(pszText1, pszText2, 5) == 0 )
と書ける。
後者の方が、比較する2つの文字列1, 文字列2の間にみごとな「対称性」があってとても美しい。
さらに、
C :
if ( strcmp(pszText1, pszText2) == 0 )  // 長さ指定なしの全体比較
if ( strncmp(pszText1, pszText2, 5) == 0 ) // 最大長さ指定有り。
C++のstd::string :
if ( str1 == str2 )            // 長さ指定なしの全体比較
if ( str1.compare(0, 5, str2) == 0 )    // 最大長さ指定有り。
のように、長さ指定が無い場合と有る場合の「対称性」もCの方が高い。

さらに、開始位置と長さを指定する引数の位置が、コンストラクタに置いては
std::string str2("Hello World");
std::string str1(str2, 長さ);
std::string str1(str2, 開始位置, 長さ);
なのに、比較においては
str1.compare(開始位置, 長さ, str2)
のように前後が逆転していて、ここでもまた、STLの文字列操作には「対称性」が無い。

なお、MFCのCStringの場合は、
CString str1, str2;
に対し、以下のように strcmp(), strncmp() に簡単に指定できる :
if ( str1 == str2 )        // 長さ指定なしの全体比較
if ( strcmp(str1, str2) == 0 )   // 長さ指定なしの全体比較
if ( strncmp(str1, str2, 5) == 0 ) // 最大長さ指定有り。
一方、std::string の場合、const char* 型への暗黙変換が出来ず、str.c_str() のように書かないといけないという困った問題がある「かも」知れない。
今のC++でどうなったかは知らない。
2020/03/05(木) 11:41:02.48ID:wTyki8t2
>>552
人による。
そして上のやり取りでもわかる通り玄人ぶったバカが変な思想を押し付けてくるが
気にしなくてもよい。
2020/03/05(木) 12:19:38.92ID:2gUuzrSw
>>561
そんなん好きなようにラッパー関数を書けばええがな。
2020/03/05(木) 13:09:53.92ID:HyVcGvBE
>>563
ラッパー関数とは関係ない話。
2020/03/05(木) 13:22:25.57ID:0hm1XC5v
>>558
ストリームよりprintfがましってのは同意だがprintfよりfmt使え
C++20から標準になる
2020/03/05(木) 13:31:47.82ID:HyVcGvBE
>>565
気になるので言っておく。
stream 入出力とは、古くから FILE, fopen, fclose, fgetc, fread などに対して使われていた言葉で、cout/cin 系専用の言葉ではない。
なんでもそうだが、言葉は有名なところで先に使っていた方が優先されるべきだ。
2020/03/05(木) 13:35:39.19ID:HyVcGvBE
>>566
1. Cのstdin, stdout, FILE, fopen, fclose, fgetc, fread 系の関数群のことは、
非常に古くから「Stream I/O」と呼ばれていた。
2. C++ では、「iostream」というような名称で cout/cin 系のクラスが定義された。
後者の事を単に「ストリーム」と言っても1とは区別が付かないのでやめて欲しい。
2020/03/05(木) 13:38:39.89ID:eBZoUINk
>>556
おい554、range-based-forはコア言語だぞ、断じてSTLではない
そもそも規格票に一言も出てこない用語でイキッてんなよ
俺がアマチュアかどうかも証拠持ってるわけねえよな

寝言は寝て言えタコ助
569デフォルトの名無しさん
垢版 |
2020/03/05(木) 13:39:59.47ID:TYdcXopQ
>>567
C++スレなので。
コンテキストで十分判別がつきます。
2020/03/05(木) 13:41:04.88ID:2gUuzrSw
何を使ってもいいけど、レイヤは切り分けた方がいいと思う。
string を使ってるときは char の配列と混同させて使うべきではないし、
char 配列を使っているなら string のことは忘れた方がいい。
どこがレイヤの境界なのかはっきりさせて。
2020/03/05(木) 13:41:08.45ID:HyVcGvBE
>>565
初めて聞いたが、書式で{1}{2}など C#に似た使い方が出来るが、
逆に、{ や } の記号を簡単にはかけなくなり printf より使いにくくなってしまう。
しかも、{1}{2}が使い易いとは思わない。むしろ%sや%dより混乱する気がする。
しかも標準ライブラリではない。
2020/03/05(木) 13:41:55.46ID:HyVcGvBE
>>569
付かない。
C++はCを前提にしているのだから、両者を混在して使うのが普通だし。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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