`std :: function`的简单版本:函数对象的生命周期?

时间:2017-08-25 10:02:48

标签: c++ lambda

我尝试构建一个非常简单的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();
}

1 个答案:

答案 0 :(得分:2)

这里确实存在生命问题:lifetime extension thanks to const only applies for local const references

您需要确保引用的函数至少与包装器一样长,或者您需要将函数复制/移动到包装器中。

  

但由于函数衰减到指针

而产生错误

您可以使用std::decay_t<T>确保将对象(例如闭包)复制/移动到包装器中。