【问题标题】:Two Questions About Lambda Use With boost::adaptors::filtered()关于 Lambda 与 boost::adaptors::filtered() 一起使用的两个问题
【发布时间】:2020-12-23 03:35:27
【问题描述】:

请考虑这个非编译代码:

#include <boost/range/adaptors.hpp>

class Stuff {
 public:
  bool var;
};

class Manager {
 /// Get everything
 std::vector<Stuff*>
 get_all_stuff() const
 {
   return list_of_stuff;
 }

 /// Get a vector of only those that whose "var" matches the "tf" argument.
 std::vector<Stuff*>
 get_some_stuff(const bool tf) const
 {
   return (get_all_stuff() |
     boost::adaptors::filtered(
       [](Stuff const& s) { return (s.var == tf); }
     )
   );
 }

 private:
  std::vector<Stuff*> list_of_stuff;
};

编译因此错误而终止:

ex.cc: In lambda function:
ex.cc:21:46: error: ‘tf’ is not captured
        [](Stuff const& s) { return (s.var == tf); }
                                              ^

1.) 如何将该函数参数带入我的 lambda?

2.) 这是一种危险的方法吗?我应该改用 std::remove_copy_if() 吗?

  • 我不担心“get_all_stuff()”返回的向量的生命周期。
  • 我担心“get_some_stuff()”返回的向量的生命周期。

【问题讨论】:

    标签: c++11 boost boost-adaptors


    【解决方案1】:

    要将外部值放入 lambda,您必须捕获它。

    [&amp;tf](Stuff const&amp; s) { return (s.var == tf);

    我在示例中使用了boost::adaptors::filter。但是 ether one 将返回一个范围,而不是一个向量对象。如果你想返回一个不同于list_of_stuff 的向量,你必须构建它。如果你从你的函数中返回它,编译器会尽可能移动它。这是一个有效的example on coliru

    #include <iostream>
    #include <boost/range/algorithm.hpp>
    #include <boost/range/adaptors.hpp>
    
    class Stuff {
    public:
        bool var;
        int id;
    };
    std::ostream& operator << (std::ostream& os, const Stuff stuff) {
        return os << std::boolalpha << stuff.id << " " << stuff.var;
    }
    using vector_type = std::vector<Stuff>;
    
    class Manager {
        /// Get everything
    public:
        auto get_all_stuff() const
        {
            return list_of_stuff;
        }
    
        // Get a vector of only those that whose "var" matches the "tf" argument.
        vector_type get_some_stuff(const bool tf) const
        {
            vector_type temp;
            for (auto item : boost::adaptors::filter(list_of_stuff,
                [&tf](Stuff const& s) { return s.var == tf; }))
                temp.push_back(item);
            return temp;
        }
    
    private:
        vector_type list_of_stuff = { {false,1},{true,2},{false,3},{true,4},{true,5} };
    };
    int main()
    {
        Manager manage;
        for (const auto item : manage.get_all_stuff())
            std::cout << item << " ";
        std::cout << std::endl;
        for (const auto item : manage.get_some_stuff(true))
            std::cout << item << " ";
        std::cout << std::endl;
    }
     
    

    【讨论】:

    • 感谢@lakeweb!您的代码是否像您的 Coliru 示例使用的那样需要 C++17?我需要 C++11...
    • 早上好。所以我去了gcc.godbolt.org,因为将MS设置为默认值(我认为是c ++ 11)没有错误。它唯一犹豫的是get_all_stuff() 的自动返回类型。将其更改为 vector_type 并编译。
    • 谢谢@lakeweb!
    猜你喜欢
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多