什么時候可以auto用作用 lambda 函式初始化的變數的型別說明符?我嘗試auto在以下程式中使用:
#include <iostream>
#include <functional>
class A
{
const std::function <void ()>* m_Lambda = nullptr;
public:
A(const std::function <void ()>& lambda): m_Lambda (&lambda) {}
void ExecuteLambda()
{
(*m_Lambda)();
}
};
void main()
{
int i1 = 1;
int i2 = 2;
const auto lambda = [&]()
{
std::cout << "i1 == " << i1 << std::endl;
std::cout << "i2 == " << i2 << std::endl;
};
A a(lambda);
a.ExecuteLambda();
}
我正在使用Visual Studio Community 2019,當我開始執行時a.ExecuteLambda(),程式停止并出現以下例外:
Unhandled exception at 0x76D9B5B2 in lambda.exe:
Microsoft C exception: std :: bad_function_call at memory location 0x00B5F434.
如果我將行更改const auto lambda = [&]()為const std::function <void ()> lambda = [&](),它就可以完美運行。為什么不允許使用auto?可以更改某些內容以允許使用它嗎?
uj5u.com熱心網友回復:
lambda 運算式不會產生std::function. 相反,它創建了一個未命名的唯一型別別,并且具有operator(). 當您將 lambda 傳遞給A的建構式時,它會創建一個臨時std::function物件,并存盤一個指向該臨時物件的指標。當A的建構式結束時,該臨時物件被銷毀,留下一個懸空指標。
要解決此問題,只需擺脫使用指標即可。那看起來像
#include <iostream>
#include <functional>
class A
{
std::function <void ()> m_Lambda;
public:
A(const std::function <void ()> lambda): m_Lambda (lambda) {}
void ExecuteLambda()
{
m_Lambda();
}
};
void main()
{
int i1 = 1;
int i2 = 2;
const auto lambda = [&]()
{
std::cout << "i1 == " << i1 << std::endl;
std::cout << "i2 == " << i2 << std::endl;
};
A a(lambda);
a.ExecuteLambda();
}
uj5u.com熱心網友回復:
您存盤晃來晃去std::function指標在你的A物件。
一個 lambda 運算式不是一個std::function物件,它是一個編譯器定義的型別,可以分配給一個std::function物件。
當您宣告lambdausing 時auto,它會獲得一個唯一型別。要將 this 系結lambda到A建構式的引數,將創建一個臨時 std::function物件,您將存盤指向該物件的指標。但是,當建構式退出時,該臨時物件會被銷毀,這就是為什么當您嘗試執行std::function.
當您更改lambdato的宣告時std::function,A建構式的引數能夠按原樣系結到該物件,并且不會創建臨時物件。
您應該std::function通過值而不是指標來傳遞和存盤物件,例如:
#include <iostream>
#include <functional>
class A
{
std::function<void()> m_Lambda;
public:
A(std::function<void()> lambda): m_Lambda(lambda) {}
void ExecuteLambda()
{
m_Lambda();
}
};
int main()
{
int i1 = 1;
int i2 = 2;
const auto lambda = [&]()
{
std::cout << "i1 == " << i1 << std::endl;
std::cout << "i2 == " << i2 << std::endl;
};
A a(lambda);
a.ExecuteLambda();
return 0;
}
在線演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/324121.html
