【问题标题】:fatal error on std::transform c++ [duplicate]std::transform c++ 上的致命错误 [重复]
【发布时间】:2017-07-17 14:20:10
【问题描述】:

我正在尝试将 foo 实例的向量转换为字符串,但在 std::transform 上出现致命错误。

data 具有以下值:

 [0] 
    [name] = John
    [size] = 3423

 [1] 
    [name] = Joseph
    [size] = 3413

代码:

struct foo {
    foo(std::string n, size_t s)
            : name(std::move(n)),
              size(s)
    {
    }
    std::string name;
    size_t size;
};

std::string server = "1";
std::vector<std::string> output;
output.reserve(static_cast<unsigned_long>(std::distance(std::begin(data), std::end(data))));

std::transform(std::begin(data),
               std::end(data),
               std::begin(output),
               [&, this](foo const& item){

            std::ostringstream result;
            data << server << ","
                 << item.name << ","
                 << item.size << ";";
            return result.str();
        });

在调试时它停在该行 stl_algo.h 中的 tranform 实现的 *__result = __unary_op(*_first) 然后转到 catch 测试框架的 FatalConditionHandler。我对捕获测试和 std::transform 都是新手。有人可以解释可能导致问题的原因以及如何解决吗?非常感谢!

【问题讨论】:

  • 应该是result &lt;&lt; server &lt;&lt; ...
  • std::vector::reserve 不会像您认为的那样做。 resize 更准确,但即便如此,您也可能希望避免这种情况。

标签: c++ std stl-algorithm catch-unit-test


【解决方案1】:

您已在 output 中保留空间,但您已将其大小保留为零。

然后您继续写入它的 begin 迭代器,就好像它有空间来保存数据一样。

然后一切都会“繁荣”。

考虑使用std::back_inserter(output) 作为目标迭代器,而不是通过std:begin(output) 编写。

您还有另一个问题:在您的 lambda 中,您有:

        std::ostringstream result;
        data << server << ","
             << item.name << ","
             << item.size << ";";
        return result.str();

这看起来是一个相当明显的错误——你无疑是有意的:

        std::ostringstream result;
        result << server << ","
             << item.name << ","
             << item.size << ";";
        return result.str();

就我个人而言,我可能会对代码的结构有所不同。我会添加类似的内容:

struct foo {
    std::string name;
    size_t size;

    // new addition:
    friend std::ostream &operator<<(std::ostream &os, foo const &f) { 
        return os << f.name << ',' << f.size;
    }
};

...那么你的转换中的 lambda 变得相当简单:

std::ostringstream result;
result << server << "," item;
return result.str();

然而,在没有stringstream 中间人的情况下这样做可能是值得考虑的。在这种情况下,你真的只需要字符串连接,而且它们会带来相当多的开销。

struct foo { 
// ...
    std::string to_string() { 
        return name + "," + size;
    }
};

那么lambda体就变成了:

return server + "," + item.to_string();

更短、更简单,而且几乎可以肯定更快。

【讨论】:

  • 非常感谢!!!这真的很有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2015-09-11
  • 2012-06-26
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
相关资源
最近更新 更多