C++ 返回不可压缩对象的元组

C++ 返回不可压缩对象的元组,c++,C++,考虑以下几点: #include <fstream> #include <tuple> #include <utility> #include <vector> const auto length_of_file = [](auto & file){ file.seekg(0, std::ios::end); std::streampos length = file.tellg(); file.seekg(0, s

考虑以下几点:

#include <fstream>
#include <tuple>
#include <utility>
#include <vector>

const auto length_of_file = [](auto & file){
    file.seekg(0, std::ios::end);
    std::streampos length = file.tellg();
    file.seekg(0, std::ios::beg);
    return length;
};

int main(int, char * []) {
    const auto check_and_read = [](const auto & filename){
        std::ifstream file(filename, std::ios::binary);
        file.exceptions(std::ios::failbit | std::ios::badbit);
        std::vector<std::byte> data(length_of_file(file));
        file.read(reinterpret_cast<char*>(data.data()), data.size());
        return std::make_tuple(file, data);
    };
    auto [file, data] = check_and_read("foo.txt");
}
nor(这个构造不应该从右值引用的元组中移动吗?)

const auto check_和_read=[](const auto&filename)
->std::tuple{
…
return std::forward_as_tuple(文件、数据);
似乎有效


是否有一些标准方法可以确保在返回多个参数时进行move构造,而不必分别移动每个参数?

没有标准函数,但这应该可以工作(C++17):

模板
自动移动到元组(类型和参数){
返回std::make_tuple(std::move(args)…);
}

移动永远不会隐式执行,除非在通常考虑省略但恰好不可能的情况下作为回退。目前(至少据我所知),这意味着隐式移动仅作为RVO和NRVO的回退发生

对于
文件
数据
,永远不会考虑省略。RVO和NRVO一开始都不适用于它们。它只会被考虑用于返回的元组,因为在这种情况下它是RVO。因此:

return std::make_tuple(std::move(file), data);
将通过RVO删除元组,移动文件并复制数据。因此,您应该执行以下操作:

return std::make_tuple(std::move(file), std::move(data));

考虑以下几点:

std::tuple<std::string, std::string> foo() {
  std::string a = "hello";

  return {a, a};
}
std::tuple foo(){ std::string a=“你好”; 返回{a,a}; } 您在特定表达式中使用的
文件
数据
可以安全地隐式移动,这并不意味着即使对于非常类似的表达式,情况也总是如此


编译器必须确定命名标识符是注定的,以便将其视为r值,这样的分析很快就会变得异常复杂。

我不这么认为-标准方法似乎是指定
std::move()每一个参数都是。好的,我根本没有考虑过。虽然如果参数被复制,可以很容易地检查,更大的问题是一些参数可能是另一个参数的一部分。
return std::make_tuple(std::move(file), data);
return std::make_tuple(std::move(file), std::move(data));
std::tuple<std::string, std::string> foo() {
  std::string a = "hello";

  return {a, a};
}