當我將可變 lambda 作為 const 參考傳遞時,代碼實際上做了什么?
為什么編譯器不引發錯誤,這是未定義的操作嗎?
為什么 f1 和 f2 使用的 f1std::function<void()>和 f2 使用的不同auto?
我發現了一個類似的問題,但我仍然不完全理解
一個 const std::function 包裝了一個非常量 operator() / 可變 lambda
#include <iostream>
#include <functional>
void call(std::function<void()> const & cb) {
cb();
cb();
}
int main() {
std::function<void()> f1 = [a = 0] () mutable {
std::cout << a << std::endl;
};
call(f1); // prints 1 2
call(f1); // prints 3 4
auto f2 = [a = 0] () mutable {
std::cout << a << std::endl;
};
call(f2); // prints 1 2
call(f2); // prints 1 2
}
https://godbolt.org/z/765endY7c
uj5u.com熱心網友回復:
在第一種情況下,兩個呼叫call(f1)都使用相同的std::function<void()>.
在第二種情況下call(f2);,隱式轉換形式 lambdastd::function<void()>啟動并創建相應的臨時物件。所以第二次呼叫使用臨時物件的新副本。
嘗試在 cppinsights 中轉換此代碼以查看更多詳細資訊。
int main()
{
class __lambda_10_32
{
public:
inline /*constexpr */ void operator()()
{
std::cout.operator<<( a).operator<<(std::endl);
}
private:
int a;
public:
// inline /*constexpr */ __lambda_10_32(const __lambda_10_32 &) noexcept = default;
// inline /*constexpr */ __lambda_10_32(__lambda_10_32 &&) noexcept = default;
__lambda_10_32(const int & _a)
: a{_a}
{}
};
std::function<void ()> f1 = std::function<void ()>(__lambda_10_32{0});
call(f1);
call(f1);
class __lambda_16_15
{
public:
inline /*constexpr */ void operator()()
{
std::cout.operator<<( a).operator<<(std::endl);
}
private:
int a;
public:
// inline /*constexpr */ __lambda_16_15(const __lambda_16_15 &) noexcept = default;
// inline /*constexpr */ __lambda_16_15(__lambda_16_15 &&) noexcept = default;
__lambda_16_15(const int & _a)
: a{_a}
{}
};
__lambda_16_15 f2 = __lambda_16_15{0};
call(std::function<void ()>(__lambda_16_15(f2)));
call(std::function<void ()>(__lambda_16_15(f2)));
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/474911.html
下一篇:編譯器宏來比較型別的位元組大小
