我尝试构建一个非常简单的std::function
版本。下面是第一个版本的代码。我的问题是关于lambda表达式中临时对象的生命周期,因为我实际上存储了对它的引用。或者物体的寿命延长了?
它尝试在T mf
内使用函数的副本(const T& mf
而不是struct F
),但是由于函数对指针的衰减而产生错误。< / p>
#include <iostream>
template<typename T>
struct F {
F(const T& f) : mf{f} {
std::cout << __PRETTY_FUNCTION__ << '\n';
}
void test() {
std::cout << __PRETTY_FUNCTION__ << '\n';
mf();
}
const T& mf;
};
template<typename T>
struct F<T*> {
F(T f) : mf{f} {
std::cout << __PRETTY_FUNCTION__ << '\n';
}
void test() {
std::cout << __PRETTY_FUNCTION__ << '\n';
mf();
}
T* mf;
};
void g() {
std::cout << __PRETTY_FUNCTION__ << '\n';
}
int main() {
F<void(void)> f1(g);
f1.test();
auto g1 = g;
F f2(g1);
f2.test();
F f3([](){ // lifetime?
std::cout << __PRETTY_FUNCTION__ << '\n';
});
f3.test();
auto l1 = [](){
std::cout << __PRETTY_FUNCTION__ << '\n';
};
F f4(l1);
f4.test();
}
答案 0 :(得分:2)
这里确实存在生命问题:lifetime extension thanks to const
only applies for local const
references。
您需要确保引用的函数至少与包装器一样长,或者您需要将函数复制/移动到包装器中。
但由于函数衰减到指针
而产生错误
您可以使用std::decay_t<T>
确保将对象(例如闭包)复制/移动到包装器中。