Skip to main content
 首页 » 编程设计

c++之创建 std::function 返回具有函数成员值的变量。分段故障

2024年11月24日18jillzhang

我正在编写一个包装类来将自定义结构成员变量包装到变体中。 给定对结构对象的引用,std::function 必须返回一个变体,它包含一个特定成员的值——std::function 最初是用它创建的。这意味着,我需要在创建函数时保存指向指定类成员的指针。

这段代码可以编译,但是当我尝试调用函数对象时,出现段错误。为什么会发生以及如何解决?

#include <functional> 
#include <variant> 
 
#include <iostream> 
 
struct Foo 
{ 
    int a, 
    b; 
    char c; 
    double d, 
    e; 
}; 
 
template <typename Struct, typename ... VarTypes> 
struct WrapMemberGet 
{ 
    template <typename T> 
    static std::function<std::variant<VarTypes...>(const Struct&)> 
            WrapGet(T(Struct::*mem_ptr)) 
    { 
                return [&](const Struct& s) 
                { 
                    return std::variant<VarTypes...>(s.*mem_ptr); 
                }; 
    } 
}; 
 
int main(int argc, const char **argv) 
{ 
    Foo  f{4, 8, 15, 16, 23}; 
 
    auto get_a = WrapMemberGet<Foo, char, int ,double>::WrapGet(&Foo::a); 
    std::variant<char, int, double> var = get_a(f); // this must hold int = 4 
 
 
    return 0; 
} 

请您参考如下方法:

您的 WrapGet 函数通过值获取一个指向成员函数的指针,并且在您的函数内部,您正在捕获该指针作为 lambda 内部的引用。这意味着在函数结束后,使用 lambda 内部的引用是悬空的,使用它会调用 UB。

为了避免它按值捕获它,而不是在 lambda 中创建一个本地拷贝。

return [=](const Struct& s) 
{ 
    return std::variant<VarTypes...>(s.*mem_ptr); 
};