C++嵌套λ

C++嵌套λ,c++,c++11,lambda,C++,C++11,Lambda,我正在研究一个带有嵌套lambda表达式的数据聚合器实现。我对lambda函数还不是很有经验,我不能100%确定我的实现想法是否可以实现 问题是:我有一个多值类,它有一个向量作为私有成员。这个私有向量的数据类型可以通过多值类的模板参数来定义。我想提供不同的聚合函数和,调和平均,平均。。。对于向量中的数据。但是:如果向量数据类型是元组,那么聚合函数也应该可用于元组的组件。下面的链接显示了我的第一次尝试,但尚未成功。我希望有人能向我解释问题所在。我认为嵌套lambda表达式存在问题,我使用: Moo

我正在研究一个带有嵌套lambda表达式的数据聚合器实现。我对lambda函数还不是很有经验,我不能100%确定我的实现想法是否可以实现

问题是:我有一个多值类,它有一个向量作为私有成员。这个私有向量的数据类型可以通过多值类的模板参数来定义。我想提供不同的聚合函数和,调和平均,平均。。。对于向量中的数据。但是:如果向量数据类型是元组,那么聚合函数也应该可用于元组的组件。下面的链接显示了我的第一次尝试,但尚未成功。我希望有人能向我解释问题所在。我认为嵌套lambda表达式存在问题,我使用:


Moo

您的代码中至少有三个问题

第一个问题已在现已删除的答复中指出:

在求和函数中,读取的是未初始化的变量

T sum() const {
    T sum; // uninitialized
    for (auto &i : *data)
    {
        std::cout << "summing from: " << i << "\n";
        sum += access(i);
    }
    return sum;
}
第二个问题是具有捕获实体的生存期问题:

template<int N, typename THead, typename... TTail>
void initSubAggregators(std::function<const std::tuple<TTypes...>&(const C&)> access) { 
    constexpr int I = N - sizeof...(TTail) - 1;
    std::get<I>(subaggregators) = Aggregator<THead, C>(AbstractAggregator<std::tuple<TTypes...>, C>::data, [&](const C &value) { return std::get<I>(access(value)); });        
    initSubAggregators<N, TTail...>(access);
}
然而,聚合器的构造函数需要一个通过常量引用返回的函数对象:

Aggregator(const std::vector<C> *data, std::function<const T&(const C&)> access)

代码中至少有三个问题

第一个问题已在现已删除的答复中指出:

在求和函数中,读取的是未初始化的变量

T sum() const {
    T sum; // uninitialized
    for (auto &i : *data)
    {
        std::cout << "summing from: " << i << "\n";
        sum += access(i);
    }
    return sum;
}
第二个问题是具有捕获实体的生存期问题:

template<int N, typename THead, typename... TTail>
void initSubAggregators(std::function<const std::tuple<TTypes...>&(const C&)> access) { 
    constexpr int I = N - sizeof...(TTail) - 1;
    std::get<I>(subaggregators) = Aggregator<THead, C>(AbstractAggregator<std::tuple<TTypes...>, C>::data, [&](const C &value) { return std::get<I>(access(value)); });        
    initSubAggregators<N, TTail...>(access);
}
然而,聚合器的构造函数需要一个通过常量引用返回的函数对象:

Aggregator(const std::vector<C> *data, std::function<const T&(const C&)> access)

如果代码库不是很大,请在这里发布。如果它是巨大的,创建一个和张贴在这里的MCVE。你看到的链接,我已经张贴?我认为这已经是一个MCVE示例。我认为在std名称空间中重新实现某些东西会导致灾难。请看,它不应该再出现故障了,至少在coliru上不会。剩下的问题是1 vsoftco指出的问题。2标识lambda也会导致UB:[]常量T&value{return value;}应该是[]常量T&value->T常量&{return value;}它当前按值返回,存储它的std::函数通过引用返回该临时值。如果代码基数不是很大,请在此处发布。如果它是巨大的,创建一个和张贴在这里的MCVE。你看到的链接,我已经张贴?我认为这已经是一个MCVE示例。我认为在std名称空间中重新实现某些东西会导致灾难。请看,它不应该再出现故障了,至少在coliru上不会。剩下的问题是1 vsoftco指出的问题。2标识lambda也会导致UB:[]const T&value{return value;}应该是[]const T&value->T const&{return value;}它当前按值返回,存储它的std::函数通过引用返回该临时值。对于这些问题可能有更好的解决方案,但我不确定它们是否值得。我会考虑重新设计类,而STD::函数< t&??> >如果您将一个按值返回的函数传递给它,它将返回一个对临时对象的引用,那么实际上应该会出现错误。为什么不呢?可能它在返回之前存储在一个中间引用参数中,这会使编译器感到困惑?@Yakk我同意。我认为它不发出警告的原因是,包含生存期问题源的头通过pragma定义为GCC system_头。在libc++的header函数库中,如果我将相关的uu invoke\u void\u return\u包装复制到一个自定义的header,我会得到警告。类似地,如果我通过_LIBCPP_HAS_NO_pragma_SYSTEM_头停用pragma。也是相关的。哦,这是一个错误的策略,在系统标题中禁用警告。我猜最终用户无法修改代码,说是的,我理解,我可以处理这个错误是缺失的。但对于模板代码,当它与用户类型交互时,缺少警告是。。。不幸的是,也许有更好的办法来解决这些问题,但我不确定它们是否值得。我会考虑重新设计类,而STD::函数< t&??> >如果您将一个按值返回的函数传递给它,它将返回一个对临时对象的引用,那么实际上应该会出现错误。为什么不呢?可能它在返回之前存储在一个中间引用参数中,这会使编译器感到困惑?@Yakk我同意。我认为它不发出警告的原因是,包含生存期问题源的头通过pragma定义为GCC system_头。在libc++的header函数库中,如果我将相关的uu invoke\u void\u return\u包装复制到一个自定义的header,我会得到警告。类似地,如果我通过_LIBCPP_HAS_NO_pragma_SYSTEM_头停用pragma。也是相关的。哦,这是一个错误的策略,在系统标题中禁用警告。我猜最终用户无法修改代码,说是的,我理解,我可以处理这个错误是缺失的。但对于模板代码,当它与u ser类型,缺少警告是。。。不幸的
Aggregator(const std::vector<C> *data, std::function<const T&(const C&)> access)
Multivalue() : Aggregator<T, T>(&data, [](const T &value) -> const T & { return value; }) { }