【问题标题】:Lambda returns empty stringLambda 返回空字符串
【发布时间】:2020-01-27 19:26:33
【问题描述】:

我有课费。

class Fee
{
private:
    std::string _code;
    int _value;
    std::string _description_EN;
    std::string _description_UA;
    std::vector<std::function<std::string()>> get_description;
public:
    //CONSTRUCTORS
    Fee(int value, std::string_view code, std::string_view description_EN, std::string_view description_UA);
    Fee(const std::string _csv_line, const char separator);
    Fee(const Fee &) = delete;
    Fee(Fee &&) = default;
    //OPERATORS
    Fee &operator=(const Fee &) = delete;
    Fee &operator=(Fee &&) = default;
    Fee &operator++() = delete;
    Fee &operator++(int) = delete;
    Fee &operator--() = delete;
    Fee &operator--(int) = delete;
    Fee &operator+(const Fee &other) = delete;
    Fee &operator-(const Fee &other) = delete;
    Fee &operator+=(const Fee &other) = delete;
    Fee &operator-=(const Fee &other) = delete;
    Fee &operator/(const Fee &other) = delete;
    Fee &operator*(const Fee &other) = delete;
    Fee &operator/=(const Fee &other) = delete;
    Fee &operator*=(const Fee &other) = delete;
    Fee &operator%(const Fee &other) = delete;
    Fee &operator%=(const Fee &other) = delete;
    //SETTERS
    void set_new_value(int value);
    //GETTERS
    std::string code();
    int value();
    std::string description(Language language = Language::EN);
    //FUNCTIONS

    //DESTRUCTOR
    ~Fee() = default;
};

以及存储费用地图的类FeeList

class FeeList
{
private:
    std::map<std::string, Fee> _fee_list;
    FeeList() = default;
public:
    static FeeList &fee_list();
    //CONSTRUCTORS
    FeeList(const FeeList &) = delete;
    FeeList(FeeList &&) = delete;
    //OPERATORS
    FeeList &operator=(const FeeList &) = delete;
    FeeList &operator=(FeeList &&) = delete;
    //SETTERS

    //GETTERS
    Fee &fee(const std::string &code);
    //FUNCTIONS
    void addFee(Fee &fee);
    void from_csv_file(const std::string &inv_file, const std::string &um_file, const std::string &id_file, const std::string &tr_file, const char separator);
    //DESTRUCTOR
    ~FeeList() = default;

};

Fee 类的构造函数有以下几行代码,它们通过 lambdas 填充“get_description”向量

get_description.resize(2);
    get_description[static_cast<size_t>(fee::Language::EN)] = [this]()->std::string{return _description_EN;};
    get_description[static_cast<size_t>(fee::Language::UA)] = [this]()->std::string{return _description_UA;};

这些 lambda 由函数“description(fee::Language::)”调用,该函数应该返回描述不恰当的语言。 实现非常简单

std::string fee::Fee::description(Language language)
{
    return get_description[static_cast<size_t>(language)]();
}

问题是从 lambda 返回的空字符串。 我创建了简单的类来测试这种方法,它按预期工作。我不知道是问题所在。我正在获取其他变量(代码和值)的值,以便正确存储对象。

编辑:这是一个指向 coliru.stacked-crooked.com 的链接,其中粘贴了我的代码并处理了提到的问题(int 值;和字符串代码;是好的字符串描述;为空)http://coliru.stacked-crooked.com/a/bc56eb53400bd1af 该文件也可以使用 Coliru 命令行找到:cat /Archive2/bc/56eb53400bd1af/main.cpp

【问题讨论】:

  • 可能由于 lambda 中的 [this] 而导致引用悬空。您认为this 指针在以下情况下会发生什么:[1] 费用已创建,[2] 费用已移至FeeList 的地图中。 [3] lambda 在 map 的费用上被调用。没有看到 MCVE 就很难判断。
  • 嗨 Mitya,欢迎来到 Stack Overflow。请提供minimal reproducible example(我们可以粘贴到例如coliru.stacked-crooked.com 并自行查看问题)。
  • 更好的设计是有std::map&lt;std::string, std::unique_ptr&lt;Fee&gt;&gt;shared_ptr,这样你就不用担心物体四处移动了。
  • 我在考虑 unique_ptr。已包含 。但首先要处理主要问题。

标签: c++ string c++11 lambda


【解决方案1】:

隐式实例化的 Fee 移动构造函数复制了 get_description 中的 lambda - 但它不会到达这些 lambda 内部并更新它们捕获的指针。它们仍然指向原来的 Fee 对象,该对象已被移出。然后,您的程序会通过访问已移动对象的方式表现出未指定的行为。

您为什么不拥有一个字符串向量,而不是两个单独的字符串变量和一个 lambda 向量?

【讨论】:

  • 感谢您的澄清。并感谢字符串向量的好主意。
  • 也许你可以建议处理这种 lambdas 行为的方法。对于未来的情况。我们如何使用用户定义的移动构造函数进入堪萨斯州。
  • 解决方案将取决于您在未来的情况下使用 lambdas 的目的。在本例中,它们是完全没有必要的。但如果出于某种原因您打算在这里使用它们,一种可能的解决方案是避免捕获 this,而是让它们将 Fee* 作为参数。
猜你喜欢
  • 2020-07-11
  • 2015-05-25
  • 2011-05-09
  • 1970-01-01
  • 2012-07-20
  • 2011-12-15
  • 2020-11-23
  • 2015-12-21
  • 2013-09-02
相关资源
最近更新 更多