C++相談室 part166 (618レス)
上下前次1-新
14: デフォルトの名無しさん (ワッチョイ b720-xasm) [] 2025/04/30(水) 12:58:39.49 ID:8LRHZRl/0(1) AAS
Windows … というか Visual Studio だと今でもデフォルトは C++14 なんだよな
機能的には C++23 まで使えるのに
15(1): デフォルトの名無しさん (ワッチョイ afaa-hOut) [sage] 2025/05/04(日) 16:06:14.75 ID:/Tm3kYwr0(1) AAS
初心者スレないんですまん。
C++でvectorとsetで同じことやらすのってどうやるの?
cout << vec << endl;
cout << st << endl;
を共通で書きたいんだけど、
template?の書き方がわかんないの
16(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/04(日) 18:28:39.39 ID:w7r9Yiaa0(1) AAS
>>15
きちんと諸々に配慮しようとすると面倒なんだけど本当にそれが出来ればよいだけならこんな感じで出来なくはない。
外部リンク:wandbox.org
17(1): 15 (ワッチョイ afaa-hOut) [sage] 2025/05/05(月) 16:19:33.69 ID:WDPor1X60(1) AAS
>>16
ありがとうございます。
std::endlの代わりに' '(空白)を使うことはできませんかね
図々しくごめんなさい
18(3): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/05(月) 17:57:32.37 ID:7tS1Ts+e0(1) AAS
>>17
まさに「諸々に配慮」と述べた部分がそれでね……。
ここで定義した operator<< と元からある operator<< の両方が char を受け取ることが可能なので
どちらを呼び出すべきか曖昧なオーバーロード (ambiguous overload) になってしまっている。
ちゃんとやる場合はここで定義する operator<< が受け取れるのはコンテナに限定しなければならない。
型に制約を付ける真っ当な方法が入ったのは C++20 からなのでそれ以前の C++ でやろうとすると回りくどいんだよ。
C++11 でなるべく簡素に書くとしたらこんな感じかな。
外部リンク:wandbox.org
19: デフォルトの名無しさん (ワッチョイ a701-uYIY) [sage] 2025/05/06(火) 12:29:11.51 ID:tCHDdC6b0(1/3) AAS
>template <class T>
>auto operator<<(std::ostream& os, const T& container_object)
> -> typename std::enable_if<!!sizeof(begin(std::declval<T>()) != end(std::declval<T>())), std::ostream&>::type {
横から何じゃこりゃw
20(2): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-6RYV) [sage] 2025/05/06(火) 12:35:30.96 ID:SvTeM3j90(1/6) AAS
declval は要らんな。
もっとキッチリしたほうがいいのか簡素にしようか迷ってちょっと変な感じになってる……。
21(1): デフォルトの名無しさん (ワッチョイ a701-uYIY) [sage] 2025/05/06(火) 13:03:38.40 ID:tCHDdC6b0(2/3) AAS
>>20
いやいや非難ではなく
俺が知っているC++じゃないw
- operatorの前のautoは何ぞ?
- !!演算子?
22(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/06(火) 13:42:19.73 ID:SvTeM3j90(2/6) AAS
>>21
関数名の前に auto を書くと仮引数の後ろに返却値の型を書けるようになる。
つまり -> から { までのところに書いてるのが返却値の型。
従来の書き方では関数の仮引数を返却値の型を決定する文脈では使えないというルールがある。
たとえば
template<class T> decltype(e) foo(const T& e) {return e;}
というようなことは出来ない。 ここで e を参照することは出来ない。
後置では返却値の型を書くところで仮引数を使ってかまわない。
template<class T> auto bar(const T& e) -> decltype(e) {return e;}
ってのはアリ。
この場合の auto は返却値の型を後置するというマークってことね。
後置にする必要がなくても後置で一貫させてるプロジェクトもたぶん結構ある。
auto がこのような用途で使えるようになったのは C++11 からなのでもう結構浸透してると思うんだけど、全く見たことないの?
!! は ! をふたつ並べてるだけ。 bool にキャストする代わりに使うイディオムなんだけど見づらいからやめたほうがよいという人も多い。
23(1): デフォルトの名無しさん (ワッチョイ a701-uYIY) [sage] 2025/05/06(火) 14:29:32.39 ID:tCHDdC6b0(3/3) AAS
>>22
解説を有難うございます
返り値を後置する記法のアドバンテージが分かりました
>>18は返り値を後置にしてるけどもこれは必須ではないということね
!!も分かりました(g++-12はなしで通ります)
24(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/06(火) 16:07:03.30 ID:SvTeM3j90(3/6) AAS
>>23
> !!も分かりました(g++-12はなしで通ります)
非型テンプレートパラメータで size_t (sizeof の結果) から bool への変換 (縮小変換) は認められていないはず……
……と思ったらこれには例外があってコンパイル時計算の文脈で実際には情報が欠落しないなら OK。
つまり整数の 0 か 1 のときに限り (型の大きさとしては小さくなる変換であっても) bool に変換が可能。
25(1): デフォルトの名無しさん (ワッチョイ 1279-k14q) [sage] 2025/05/06(火) 17:28:20.12 ID:GbYxwNEQ0(1) AAS
非0ならtrueやないんか
26: はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/06(火) 18:05:53.77 ID:SvTeM3j90(4/6) AAS
>>25
せやで。 こういうときは変換されない。
template<bool num>
class foo {};
int main(void) {
foo<2> bar;
}
通常の暗黙の変換で許されていても非型テンプレートパラメタでは縮小変換はされないので↓みたいなのも駄目。
template<unsigned char num>
class foo {};
int main(void) {
foo<1000> bar;
}
27(1): 15 (ワッチョイ afaa-hOut) [sage] 2025/05/06(火) 18:35:49.00 ID:jhNAw2EC0(1/2) AAS
>>18
重ね重ねありがとうございます。
なんとか理解してみます。
C++20だとどうなります?
一応、C++の新機能ってぺージ見たんですけど、よくんからなくて
28: デフォルトの名無しさん (アウアウウー Sac3-7Zak) [sage] 2025/05/06(火) 18:36:01.85 ID:nZOyiL0Ra(1) AAS
enable_ifは便利だけど使ったら負け感が半端無い
29(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/06(火) 19:26:25.22 ID:SvTeM3j90(5/6) AAS
この場合は enable_if は本来の意味で使ってないしな。
30(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/06(火) 20:07:39.20 ID:SvTeM3j90(6/6) AAS
>>27
こんな感じかな。
外部リンク:wandbox.org
C++20 からはイテレータの概念も再編されて range という概念で扱うのが好ましいということになり、コンテナは range の一種だったことになった。
コンテナの中のここからここまでという範囲を表すものを中心にした考え方で、コンテナ自身も range だし、コンテナの除き窓のような view も range 。
Rust とか Go で言うスライスみたいなもん。
で、テンプレート引数として受け取った T が std::ranges::range の制約を満たすものなんやでという制約を入れることによってそうじゃないものはマッチしないように出来るし、
他の operator<< の候補にマッチするものがあるのならそっちが選ばれるようになる。
31: 15 (ワッチョイ afaa-hOut) [sage] 2025/05/06(火) 21:47:53.45 ID:jhNAw2EC0(2/2) AAS
>>30
ありがとうございます。
rangeはときどき見てたんですけど、ぱっと見あんまり必要性がわからなかったんですけど、こういう理由があったんですね。
これから時間があるときは、rangeを意識して書きたいと思います。
ありがとうございました
32(1): デフォルトの名無しさん (ワッチョイ df01-7ORQ) [sage] 2025/05/07(水) 09:06:41.19 ID:pa9hjTXM0(1) AAS
>>29
ostreamあんま詳しくないので本来の意味じゃないってのが良くわからんかった
コンテナでなければ弾くようにしてるんだと思うけどsizeofで括ってるのは式自体が評価されないようにするため?
33: はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/07(水) 09:38:53.26 ID:jrPMMEx+0(1/4) AAS
>>32
そう。
実態としては sizeof の中の式が成立するかどうかだけが判定基準になってる。
sizeof が 0 を返すことはあり得ないわけだし sizeof の中の式が成立しないなら enable_if で判定する以前に弾かれるわけなので enable_if は判定の役に立ってない。
式を書く場所があるならなんでもよかったんだけど最終的には ostream& になってもらわないといけないので enable_if が楽だったというだけ。
34: デフォルトの名無しさん (ササクッテロラ Spc7-7ORQ) [sage] 2025/05/07(水) 09:53:44.11 ID:zHwjwbR2p(1) AAS
あーなるほど、意味がわかった
ありがとう
35(3): デフォルトの名無しさん (ワッチョイ 1202-mpUa) [sage] 2025/05/07(水) 22:31:24.20 ID:OFqp/W1O0(1/2) AAS
vectorって、
宣言時に、要素数と初期値を設定できないっけ?
気持ちとしては、、
↓
vector<int> my_data(3) = { 6, 8, 44 };
36(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/07(水) 22:42:31.19 ID:jrPMMEx+0(2/4) AAS
>>35
できない。
そうしたい理由としては指定した個数分の要素が間違いなく与えられているようにってこと?
37: デフォルトの名無しさん (ワッチョイ a701-uYIY) [sage] 2025/05/07(水) 22:57:31.27 ID:F57QgFhN0(1) AAS
>>35
arrayはそれに近いな
array<int, 3> my_data = {6, 8, 44};
38(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 6332-x8bn) [sage] 2025/05/07(水) 23:14:20.16 ID:jrPMMEx+0(3/4) AAS
>>35
与えている要素の個数に間違いがないことを確実にしたいというのが目的だとしたらこういう関数を定義するのはどうだろう。
外部リンク:wandbox.org
上下前次1-新書関写板覧索設栞歴
あと 580 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.017s