std::transform c++ 上的致命错误
fatal error on std::transform c++
我正在尝试将 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 都是新手。有人可以解释可能导致问题的原因以及解决方法吗?非常感谢!
您在 output
中保留了 space,但您将其大小保留为零。
然后您继续写入它的 begin
迭代器,就像它有 space 来保存数据一样。
然后一切顺利"boom"。
考虑使用 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();
更短、更简单,而且几乎肯定更快。
我正在尝试将 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 都是新手。有人可以解释可能导致问题的原因以及解决方法吗?非常感谢!
您在 output
中保留了 space,但您将其大小保留为零。
然后您继续写入它的 begin
迭代器,就像它有 space 来保存数据一样。
然后一切顺利"boom"。
考虑使用 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();
更短、更简单,而且几乎肯定更快。