结构化绑定是否适用于 std::vector?
Does structured binding work with std::vector?
是否可以对向量使用结构化绑定?
例如
std::vector<int> vec{1, 2, 3};
auto [a, b, c] = vec;
不幸的是,上面的代码不起作用(在 GCC 下(,但也许有一种不同的方法(使用结构化绑定(允许将向量的前三个值分配给三个变量。
结构化绑定仅在编译时已知结构时才有效。vector
的情况并非如此.
虽然您确实知道各个元素的结构,但您不知道元素的数量,这就是您在问题中试图分解的内容。同样,您只能在编译时已知大小的数组类型上使用结构化绑定。考虑:
void f(std::array<int, 3> arr1,
int (&arr2)[3],
int (&arr3)[])
{
auto [a1,b1,c1] = arr1;
auto [a2,b2,c2] = arr2;
auto [a3,b3,c3] = arr3;
}
前两行将起作用,但最后一行将无法编译,因为在编译时不知道arr3
的大小。在Godbolt上尝试一下。
在向量上创建一个基本的包装器非常简单,可以像元组一样访问它。由于确实无法在编译时检索向量的大小,因此如果您尝试解构太短的向量,则会引发std::out_of_range
。不幸的是,我不知道推断请求绑定数量的方法,所以这是明确的。
完整代码:
#include <string>
#include <vector>
#include <iostream>
template <class T, std::size_t N>
struct vector_binder {
std::vector<T> &vec;
template <std::size_t I>
T &get() {
return vec.at(I);
}
};
namespace std {
template<class T, std::size_t N>
struct tuple_size<vector_binder<T, N>>
: std::integral_constant<std::size_t, N> { };
template<std::size_t I, std::size_t N, class T>
struct tuple_element<I, vector_binder<T, N>> { using type = T; };
}
template <std::size_t N, class T>
auto dissect(std::vector<T> &vec) {
return vector_binder<T, N>{vec};
}
int main() {
std::vector<int> v{1, 2, 3};
auto [a, b] = dissect<2>(v);
a = 5;
std::cout << v[0] << 'n'; // Has changed v through a as expected.
}
vector_binder
的右值和常量版本以及更好的名称留给读者作为练习:)
在科里鲁现场观看
不理想,因为它更冗长,但你也可以这样做:
auto [a, b, c] = array<int, 3>({vec[0], vec[1], vec[2]});
我不同意不知道容器的元素数量应该阻止与其元素的结构化绑定的概念。我的理由是,由于以下内容不会引发编译时错误:
auto a = vec[0];
auto b = vec[1];
auto c = vec[2];
(即使 VEC[2] 在运行时可能超出范围(,上述结构化绑定也应该如此。这意味着,为什么不把它留给用户来确保 vector 在运行时具有正确的长度,如果不是这种情况,则抛出超出范围的异常呢?这基本上就是我们在语言中其他地方使用向量的方式。
相关文章:
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 连接和压缩标准::vector<std::字符串的最佳方法>
- C++从 std::vector<std::function<中删除 std::function>>
- 如何在构造函数初始值设定项列表中使用 n 个元素初始化 std::vector<std::time_t>
- 如何使用 CUDA 将 std::vector<std::string> 复制到 GPU 设备
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 将 std::vector<std::unique_ptr<T>> 移动到 std::vector<std::shared_ptr<T>>
- 如何从 boost::container::vector<std::string>::iterator 访问索引和对象?
- 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
- 为什么转置这个 std::vector<std::vector<std::string> > 这么慢?
- 是否有可能在没有复制的情况下传递 std::vector<int> 作为参数来获得 std::vector<std::array<int, 3>>?
- 在 boost::<double>asio::buffer 中使用像 std::vector<std::complex> 这样的参数
- 如何从 std::initializer_list<char const* 构建 std::vector<std::string>>
- 如何检查 std::vector<std::string> 的元素是否以某个子字符串开头?
- 在 std::vector<std::vector 中重新存储内部向量<TYPE>>
- 将 std::vector<std::string> 转换为 const char* const*
- 不能将结构push_back() 转换为 std::vector<std::shared_ptr<theStruct>> theVector
- SWIG:传递一个 std::vector< std::vector <double> >指向 python 的指针
- 将 std::vector<std::p air<const K, V>*> 转换为 std::vector<std::p air<const K, V>&g