C++ 结构绑定std::tuple中断std::stringstream

C++ 结构绑定std::tuple中断std::stringstream,c++,stringstream,stdtuple,C++,Stringstream,Stdtuple,考虑以下代码: #include <iostream> #include <fstream> #include <string> #include <sstream> #include <tuple> auto read_data(std::ifstream& training_file) { if (!training_file) { throw std::runtime_error{"Error:

考虑以下代码:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <tuple>

auto read_data(std::ifstream& training_file) {
    if (!training_file) {
        throw std::runtime_error{"Error: could not open one or more files"};
    }

    std::stringstream training{};
    training << training_file.rdbuf();

    std::cout << training.str() << '\n';

    return std::tie(training);
}

int main() {
    std::ifstream input{"input.txt"};

    auto [train] = read_data(input);

    std::cout << train.str() << '\n';
    std::cout << "x" << '\n';
}
注意-第二行之后没有换行符

此程序的意外输出为:

显然,Ź$~Ź,部分不应该在那里

请注意,我正在输出完全相同的文件内容。我不知道这意外的部分是从哪里来的

当玩代码时,它变得更加奇怪。如果我将std::cout注释掉,这是一个本地:

std::stringstream training{};
这将返回对所述本地的引用,并封装在元组中:

return std::tie(training);
所以自动[火车]=。。。;将名称train初始化为悬挂引用。程序的行为未定义

如果需要返回两个或两个以上的流,则只需在您选择的tuple/array/custom聚合中预定义它们:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <tuple>
#include <array>

auto read_data() {
    std::array<std::stringstream,2> trainings{
        std::stringstream{},
        std::stringstream{}
    };

    return trainings;
}

int main() {

    auto train = read_data();

    std::cout << train[1].str() << '\n';
    std::cout << "x" << '\n';
}

复制省略保证额外的对象要么被完全删除,要么移动到适当的位置

是啊,那真是太傻了。有没有关于从函数返回两个std::stringstreams的优雅方法的想法?std::tuple可以存储对象本身吗?我怀疑会有问题,因为std::stringstream是不可压缩的。我可以把它移到包装器中并返回吗?@Fureeish-只需按值返回即可。复制省略算法要么完全去除多余的对象,要么在目标处移动并构造它。若我只有一个std::stringstream要返回,就像原始问题一样,那个就太好了,但我注意到,我最初使用std::tie,因为我创建了两个流,我希望返回它们,并使用结构化绑定引用它们。编辑:当然我可以调用read_数据两次并将结果存储在变量中,但我真的很想知道实现原始目标的方法,即使这毕竟不是首选的方法谢谢!它非常有用,特别是因为可以将结构化绑定用于数组和std::array。但愿我能投票并接受两次!
gdb: unknown target exception 0x80000001 at 0x7ff909e845c0
Thread 1 received signal ?, Unknown signal.
0x00007ff909e845c0 in ?? ()
0 0
0 0 0 0
0 0 0 0
30 20 30 20 30 20 30 0D 0A 30 20 30 20 30 20 30
std::stringstream training{};
return std::tie(training);
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <tuple>
#include <array>

auto read_data() {
    std::array<std::stringstream,2> trainings{
        std::stringstream{},
        std::stringstream{}
    };

    return trainings;
}

int main() {

    auto train = read_data();

    std::cout << train[1].str() << '\n';
    std::cout << "x" << '\n';
}