返回无用对象的元组
return tuple of uncopyable objects
考虑以下内容:
#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");
}
这不会编译,因为它想要复制file
,这是不可能的。
return std::make_tuple(std::move(file), data);
有效,但是我问自己»这是否意味着它正在复制而不是现在移动data
?
却都不
const auto check_and_read = [](const auto & filename)
-> std::tuple<std::ifstream, std::vector<std::byte>> {
…
return {file, data}
也不(不应该从RVALUE参考的元组中进行此移动构造吗?(
const auto check_and_read = [](const auto & filename)
-> std::tuple<std::ifstream, std::vector<std::byte>> {
…
return std::forward_as_tuple(file, data);
似乎有效。
是否有一些标准方法可以确保在返回多个参数的返回而无需单独std::move
的情况下移动施工?
考虑以下内容:
std::tuple<std::string, std::string> foo() {
std::string a = "hello";
return {a, a};
}
您在特定表达式中使用file
和data
的用法隐含地安全可移动并不意味着即使对于非常相似的表达方式也是如此。
编译器必须确定命名的标识符注定要将其视为R值,并且这种分析将很快变得不合理地复杂。
没有标准功能,但这应该起作用(C 17(:
template <class... Types>
auto move_to_tuple(Types&&... args) {
return std::make_tuple(std::move(args)...);
}
移动永远不会被隐式执行,除非在通常考虑省略但碰巧是不可能的情况下作为后备。目前(嗯,至少据我所知(,这意味着隐式移动只能作为RVO和NRVO的后备。
。 file
和data
永远不会考虑省略。RVO和NRVO都不适用于他们。仅考虑返回的元组,因为在这种情况下是RVO。因此:
return std::make_tuple(std::move(file), data);
将通过RVO填充元组,移动文件并复制数据。所以你应该这样做:
return std::make_tuple(std::move(file), std::move(data));
相关文章:
- C++:TypeDef使用元组
- Pybind11:将元组列表从Python传递到C++
- 如何使用单独文件中的派生类访问友元函数对象
- 重载元组索引运算符-C++
- 在C++中,如何通过几种类型从元组中选择多个元素
- 返回本地对象的元组
- 如何通过指向元组的共享指针删除对象
- std::tie 和元组中返回的对象的生存期
- 创建对满足特定谓词的对象的引用元组
- 如何构造不可移动不可复制对象的元组?
- 返回无用对象的元组
- 为什么在元组初始化中构造对象
- 如何从对象中获取对元组尾部的引用 std::tuple<Head,Tail...>
- 如何初始化非默认可构造不可复制对象的元组
- 构建一组对象并将它们放入元组中
- 在c++11中,为包含std::元组的对象键入Erasure
- 对一个对象上的每个元组元素调用函数,不进行递归
- c++ -从其他对象继承std::元组,并为其添加虚函数
- 将动态数组对象传递给友元函数不会累积计数器
- 将从元组派生的对象放入C++中的向量中