访问元组向量中的元素 C++
Accessing elements in a vector of tuples C++
我有以下代码。
#include <iostream>
#include <vector>
#include <tuple>
int main() {
std::vector<std::tuple<int, int>> edges(4,{1,2});
for (auto i = std::begin (edges); i != std::end (edges); ++i) {
std::cout << std::get<0>(i) << " "<< std::get<1>(i)<< " ";
}
}
在我看来,这是有道理的,我有一个正在初始化的元组向量。然后我遍历向量分别打印元组的两个元素。
但是代码 doesn't work 返回
8:26: error: no matching function for call to 'get'
std::cout << std::get<0>(i) << " "<< std::get<1>(i)<< " ";
^~~~~~~~~~~
谁能解释一下为什么?
我会改为基于范围的for
循环
for (auto const& edge : edges) {
std::cout << std::get<0>(edge) << " "<< std::get<1>(edge)<< " ";
}
否则要访问每条边,您需要使用 *
取消引用您的迭代器以获取实际的元组本身
for (auto iter = std::begin(edges); iter != std::end(edges); ++iter) {
std::cout << std::get<0>(*iter) << " "<< std::get<1>(*iter)<< " ";
}
i
不是 std::tuple<int, int>
,它是指向一个 (std::tuple<int, int>*
) 的指针(迭代器);你需要取消引用它。
如果您能够升级到 C++17,则可以在基于范围的 for 循环中使用结构化绑定:
for (auto [a, b] : edges) {
std::cout << a << " " << b << " ";
}
错误消息可能令人生畏。有时您需要深入挖掘才能找到相关部分。对于你的代码,当compiled with gcc时,这部分错误信息是一个很好的提示:
In file included from <source>:3:
/opt/compiler-explorer/gcc-trunk-20211209/include/c++/12.0.0/tuple:1380:5: note: candidate: 'template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_UTypes ...> >& std::get(tuple<_UTypes ...>&)'
1380 | get(tuple<_Elements...>& __t) noexcept
| ^~~
/opt/compiler-explorer/gcc-trunk-20211209/include/c++/12.0.0/tuple:1380:5: note: template argument deduction/substitution failed:
<source>:8:37: note: '__gnu_cxx::__normal_iterator<std::tuple<int, int>*, std::vector<std::tuple<int, int> > >' is not derived from 'std::tuple<_UTypes ...>'
8 | std::cout << std::get<0>(i) << " "<< std::get<1>(i)<< " ";
| ~~~~~~~~~~~^~~
消息中使用的编译器内部名称并没有使它变得更容易,尽管消息试图告诉的是有一些 get
将元组作为参数和 returns它的元素 (constexpr std::__tuple_element_t<__i, std::tuple<_UTypes ...> >& std::get(tuple<_UTypes ...>&)
),但您传递的是来自元组向量 (__gnu_cxx::__normal_iterator<std::tuple<int, int>*, std::vector<std::tuple<int, int> > >'
) 的迭代器。他们不匹配。您需要取消引用迭代器以获取对元组的引用。
我有以下代码。
#include <iostream>
#include <vector>
#include <tuple>
int main() {
std::vector<std::tuple<int, int>> edges(4,{1,2});
for (auto i = std::begin (edges); i != std::end (edges); ++i) {
std::cout << std::get<0>(i) << " "<< std::get<1>(i)<< " ";
}
}
在我看来,这是有道理的,我有一个正在初始化的元组向量。然后我遍历向量分别打印元组的两个元素。
但是代码 doesn't work 返回
8:26: error: no matching function for call to 'get'
std::cout << std::get<0>(i) << " "<< std::get<1>(i)<< " ";
^~~~~~~~~~~
谁能解释一下为什么?
我会改为基于范围的for
循环
for (auto const& edge : edges) {
std::cout << std::get<0>(edge) << " "<< std::get<1>(edge)<< " ";
}
否则要访问每条边,您需要使用 *
取消引用您的迭代器以获取实际的元组本身
for (auto iter = std::begin(edges); iter != std::end(edges); ++iter) {
std::cout << std::get<0>(*iter) << " "<< std::get<1>(*iter)<< " ";
}
i
不是 std::tuple<int, int>
,它是指向一个 (std::tuple<int, int>*
) 的指针(迭代器);你需要取消引用它。
如果您能够升级到 C++17,则可以在基于范围的 for 循环中使用结构化绑定:
for (auto [a, b] : edges) {
std::cout << a << " " << b << " ";
}
错误消息可能令人生畏。有时您需要深入挖掘才能找到相关部分。对于你的代码,当compiled with gcc时,这部分错误信息是一个很好的提示:
In file included from <source>:3:
/opt/compiler-explorer/gcc-trunk-20211209/include/c++/12.0.0/tuple:1380:5: note: candidate: 'template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_UTypes ...> >& std::get(tuple<_UTypes ...>&)'
1380 | get(tuple<_Elements...>& __t) noexcept
| ^~~
/opt/compiler-explorer/gcc-trunk-20211209/include/c++/12.0.0/tuple:1380:5: note: template argument deduction/substitution failed:
<source>:8:37: note: '__gnu_cxx::__normal_iterator<std::tuple<int, int>*, std::vector<std::tuple<int, int> > >' is not derived from 'std::tuple<_UTypes ...>'
8 | std::cout << std::get<0>(i) << " "<< std::get<1>(i)<< " ";
| ~~~~~~~~~~~^~~
消息中使用的编译器内部名称并没有使它变得更容易,尽管消息试图告诉的是有一些 get
将元组作为参数和 returns它的元素 (constexpr std::__tuple_element_t<__i, std::tuple<_UTypes ...> >& std::get(tuple<_UTypes ...>&)
),但您传递的是来自元组向量 (__gnu_cxx::__normal_iterator<std::tuple<int, int>*, std::vector<std::tuple<int, int> > >'
) 的迭代器。他们不匹配。您需要取消引用迭代器以获取对元组的引用。