C++相談室 part165 at TECH
[2ch|▼Menu]
60:デフォルトの名無しさん (ワッチョイ 6ecf-ekUX)
23/11/18 16:16:09.27 5MckQHFy0.net
ラムダの参照キャプチャってconst参照に指定できないんだっけ?微妙に不便だな。

61:デフォルトの名無しさん
23/11/18 20:47:45.62 GRi2RJZB0.net
>>60
これじゃだめ?
#include <iostream>
using namespace std;
int main () {
const int a {0};
int b {0};
[&a, &b = const_cast <const int &> (b)] () {
++ a; // X
++ b; // X
} ();
return 0;
}

62:デフォルトの名無しさん
23/11/26 06:27:21.37 DSb557XU0.net
C++20 RangesはMicrosoftの説明がわかりやすかった

63:デフォルトの名無しさん
23/12/05 10:33:06.64 HLoKrA0o0.net
ふと今更思ったんだけど
ポインターpに対して演算子*が返す*pは、
値じゃなくて参照?

64:デフォルトの名無しさん
23/12/05 11:05:15.15 E3GJtsiR0.net
#include <type_traits>
#include <iostream>
using namespace std;
int main () {
int value {0};
int *p {&value};
cout << is_reference <int>::value << '\n';
cout << is_reference <int &>::value << '\n';
cout << is_reference <decltype (value)>::value << '\n';
cout << is_reference <decltype (*p)>::value << '\n';
return 0;
}

65:デフォルトの名無しさん
23/12/05 11:09:19.91 IVr4NrBA0.net
>>63
参照ってのが何を意味しているか分からんが
普通はポインターの示す場所の内容だ

66:はちみつ餃子
23/12/05 11:22:18.93 z5PiblaY0.net
>>63
ポインター p に対して *p とした場合の型は参照ではない。
たぶん >>64 は *p が参照と言いたいつもりで書いているんだと思うけど
decltype に与えられる式の型が T 型の lvalue だった場合には T& が返されるルールなので
その式が参照でなくても参照が返されることがある。

67:はちみつ餃子
23/12/05 11:24:42.01 z5PiblaY0.net
あ、ごめん。 完全に間違った説明してたわ。 忘れて……。 恥ずかしい。

68:はちみつ餃子
23/12/05 11:34:00.06 z5PiblaY0.net
と思ってよく仕様を読んでみたらやっぱりこの (>>66) 考え方で正しいはず。
式が識別子式の時に限っては decltype は参照にならず式の型そのままで返すせいで decltype(value) は参照にならないが、
value と *p は型システム的にも値カテゴリ的にも同じだわ。

69:デフォルトの名無しさん
23/12/05 12:43:28.97 E3GJtsiR0.net
>>68
なるほどー! 横からだが勉強になった

70:デフォルトの名無しさん
23/12/05 12:48:03.77 E3GJtsiR0.net
巷のスマートポインタはoperator*で参照型を返すので
生ポインタも同じかと思ってたよ

71:はちみつ餃子
23/12/05 13:28:25.92 z5PiblaY0.net
互換性の都合とかがあるから仕方ないね。
場合分けが大量にあって単純な一般原則の組み合わせにはなってないから仕様を読み解くのがしんどい……

72:デフォルトの名無しさん
23/12/11 15:17:51.77 7vxydTfj0.net
ある構造体Aがあります
Aの比較関数が複数ありますcompA0,compA1,compA2,...
比較関数の関数ポインタがありますcompA
compA = &compA2;
別の構造体Bがあります
BはAを内包しています
struct B{ A a; ... };
この構造体Bを、Aの比較関数ポインタcompAで比較してソートするにはどう記述すればよいですか?
std::vector<B> bs;
bs.push_back(...);...
std::sort(bs.begin(),bs.end(),?);
できればラムダ式を使わずにできるとありがたいです

73:デフォルトの名無しさん
23/12/11 15:22:02.06 F1R6HyeLM.net
>>72
ラムダ式使った方が良いと思うけど本当にラムダ式なしが良い?

74:デフォルトの名無しさん
23/12/11 15:29:19.94 7vxydTfj0.net
使われると、ラムダ式の質問をすることになると思います・・・

75:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-pD6R)
23/12/11 15:45:20.57 wAhsIAfi0.net
>>72
もし C++20 を使えるなら (std::sort と違って) std::ranges::sort では比較関数とは別に
比較すべき要素を取り出す操作をプロジェクションとして与えることが出来るから
これ一発でいけてだいぶん楽できる。

std::ranges::sort(bs, compA, &B::a);

76:デフォルトの名無しさん (ワッチョイ d701-Qbcu)
23/12/11 16:01:10.52 dil4ai7q0.net
>>75
すげ! 今そんなのあるんやね

77:デフォルトの名無しさん
23/12/11 16:34:20.59 dil4ai7q0.net
>>74
思い出すのがしんどくなってきた
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
struct A {int value_;};
bool compA2 (const A &lhs, const A &rhs) {
return lhs.value_ < rhs.value_;
}
struct B {A a;};
int main () {
vector <B> bs;
bool (*compA) (const A &, const A &) {compA2};
sort (bs.begin(), bs.end(), bind (compA, bind (mem_fn (&B::a), placeholders::_1), bind (mem_fn (&B::a), placeholders::_2)));
sort (bs.begin(), bs.end(), [compA] (const auto &lhs, const auto &rhs) {return (*compA) (lhs.a, rhs.a);});
return 0;
}

78:デフォルトの名無しさん
23/12/11 17:14:54.00 cVrrslE50.net
>>75
>>77
お二方、ありがとうございます
参考にして組んでみます

79:はちみつ餃子
23/12/11 17:25:04.51 wAhsIAfi0.net
その場で合成するのはさすがに見通しが悪すぎるので、
C++11 頃の C++ を仮定して私がやるならまずアダプタを作ると思う。
ちょっと雑ですまんがとりあえずこんな感じ。
class compB_adaptor {
private:
using comparator = std::function<bool(const A&, const A&)>;
comparator compA;
public:
compB_adaptor(comparator comp) : compA(comp) {}
bool operator()(const B& x, const B& y) {
return compA(x.a, y.a);
}
};
使うときには間にひとつ挟むだけで済む。
std::sort(bs.begin(), bs.end(), compB_adaptor(compA));

80:デフォルトの名無しさん (ワッチョイ 771f-oseA)
23/12/11 22:08:32.24 cVrrslE50.net
>>79
求めていたものそのものであったため、採用させていただきました
ありがとうございます


最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

147日前に更新/26 KB
担当:undef