トップ回答者
ラムダ式の場合の定義変換について

質問
-
いつもお世話になっております。
VS2015U3 / Windows Kits(10.0.14393.0)で作業しています。-- A.h --- strcut Elm { int hclr; long hstl; }; --- proc.h --- #include "A.h" CData data{ int m_Color; long m_Style; } --- proc.cpp --- #include "proc.h" struct CHGTABLE { std::vector<int> clr; ... }; ... Elm e; CData Sen; ... auto elmnew = [&,e](auto obj){ auto tmpe = std::make_unique<Elm>(e); return [&,tmpe0=std::move(tmpe)]() mutable{ tmpe0->hclr = CHGTABLE.clr[obj.m_Color]; return *tmpe0; }; }; ... Elm Senelm = elmnew(Sen); //-->
ラムダ式を用いて値を変更することをしたいのですが、//ーー>の部分において、
"lambda[]Elm() mutable->Elm"から、"Elm"への適切なユーザー定義変換が存在しません
とエラーが出ます。
お忙しいところ恐縮ですが、ラムダ式の場合の定義変換方法をご教示いただけますと幸いです。
どうぞ宜しくお願い致します。
- 編集済み SHIN109 2021年8月17日 2:17 戻す変数名を修正
回答
-
SHIN109さん、こんにちは。フォーラムオペレーターのKumoです。
MSDNフォーラムにご投稿くださいましてありがとうございます。
ラムダ関数でコピーによってキャプチャされた変数の値を変更したいのでしょうか。
そうであれば、私の知る限りでは、できないかと思います。
具体的にはC++ でのラムダ式をご参照ください。
通常、ラムダの関数呼び出し演算子は const-by-value ですが、mutableキーワードを使用するとこれを取り消します。mutableデータ メンバーは生成できません。
mutable仕様を使用すると、ラムダ式の本体で、値によってキャプチャされる変数を変更できます。
mutable ではコピーを変更できますが、元のコピーは変更できません。
例えば:
#include <iostream> using namespace std; int main() { size_t t = 9; auto f = [t] () mutable {return ++t; }; cout << f() << endl; cout << f() << endl; cout << "t:" << t << endl; return 0; }
ここでは、値によってキャプチャされた変数tは、最初にキャプチャされた初期値が9であり、fを1回呼び出した後、10になります。再度呼び出されると、11になります。ただし、main()関数で定義されている最終出力tは値キャプチャであるため、その値は変更されず、最終的に9が出力されます。
どうぞよろしくお願いいたします。MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~
- 回答としてマーク SHIN109 2021年8月17日 6:25
すべての返信
-
SHIN109さん、こんにちは。フォーラムオペレーターのKumoです。
MSDNフォーラムにご投稿くださいましてありがとうございます。
ラムダ関数でコピーによってキャプチャされた変数の値を変更したいのでしょうか。
そうであれば、私の知る限りでは、できないかと思います。
具体的にはC++ でのラムダ式をご参照ください。
通常、ラムダの関数呼び出し演算子は const-by-value ですが、mutableキーワードを使用するとこれを取り消します。mutableデータ メンバーは生成できません。
mutable仕様を使用すると、ラムダ式の本体で、値によってキャプチャされる変数を変更できます。
mutable ではコピーを変更できますが、元のコピーは変更できません。
例えば:
#include <iostream> using namespace std; int main() { size_t t = 9; auto f = [t] () mutable {return ++t; }; cout << f() << endl; cout << f() << endl; cout << "t:" << t << endl; return 0; }
ここでは、値によってキャプチャされた変数tは、最初にキャプチャされた初期値が9であり、fを1回呼び出した後、10になります。再度呼び出されると、11になります。ただし、main()関数で定義されている最終出力tは値キャプチャであるため、その値は変更されず、最終的に9が出力されます。
どうぞよろしくお願いいたします。MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~
- 回答としてマーク SHIN109 2021年8月17日 6:25
-
フォーラムオペレーター Kumo 様
レス、ありがとうございます。
知識が乏しく、誤解を生む質問ばかりで申し訳ございません。
調査中にmutableすることを知り、進めながらよく理解していない箇所(unique_ptrのスコープでdeleteされること等)が重なり、難しく考え混乱していた状態だと分かってきました。
その状態でしたので、質問内容も提示するサンプルコードも意味不明になって、佐祐理様の仰るところではないかと思います。
コピー元は変更せずに、コピーを変更して使用するという意味合いで、仰る通りです。
リンクもありがとうございました。
結論としては、佐祐理様への回答で記載したauto elmnew = [&,e](auto obj) mutable{ e.hclr = CHGTABLE.clr[obj.m_Color]; return e; };
の形で出来ました。
佐祐理 様
大変失礼しました。レスありがとうございました。
お二方、お忙しい中、ご教示ありがとうございました。
いつもお手数お掛けして申し訳ありませんが、今後ともどうぞ宜しくお願いいたします。