自动解包一对迭代器
Auto-unpacking a pair of iterators
在C++中,如果一个函数returns一个std::pair<int, int>
,我们可以这样自动接收它:
auto pr = some_function();
std::cout << pr.first << ' ' << pr.second;
现在,C++17 标准提供了一种将这对直接解包为单独变量的漂亮方法,如下所示:
auto [x, y] = some_function();
std::cout << x << ' ' << y;
然后是std::minmax_element()
库函数,其中returns一对迭代器。因此,如果我将 vector<int>
传递给此函数,它会返回一对指向向量中最小和最大元素的迭代器。
现在我可以像往常一样接受这些迭代器的一种方法,然后按如下方式取消引用它们。
std::vector<int> v = {4,1,3,2,5};
auto [x, y] = std::minmax_element(v.begin(), v.end());
std::cout << (*x) << ' ' << (*y); // notice the asterisk(*)
现在我的问题是:有没有办法在解包时取消对它们的引用?或者更准确地说,给定以下代码,我可以替换 var1
和var2
使用有效的 C++ 并打印那些迭代器指向的值?
std::vector<int> v = {4,1,3,2,5};
auto [var1, var2] = std::minmax_element(v.begin(), v.end());
std::cout << var1 << ' ' << var2; // notice there is NO asterisk(*)
当然可以。编写一个函数,接受一对可取消引用的事物和 returns 取消引用它们的结果:
template <typename Iterator,
typename R = typename std::iterator_traits<Iterator>::reference>
auto deref(std::pair<Iterator, Iterator> p)
-> std::pair<R, R>
{
return {*p.first, *p.second};
}
然后使用那个函数:
auto [var1, var2] = deref(std::minmax_element(v.begin(), v.end()));
请注意,如果范围为空,则这是 UB,因为您要取消引用结束迭代器两次。
或者,更好:
struct deref_t {
template <typename It,
typename R = typename std::iterator_traits<Iterator>::reference>
friend auto operator|(std::pair<It, It> p, deref_t)
-> std::pair<R, R>
{
return { *p.first, *p.second };
}
};
inline constexpr deref_t deref{};
允许:
auto [var1, var2] = std::minmax_element(v.begin(), v.end()) | deref;
在C++中,如果一个函数returns一个std::pair<int, int>
,我们可以这样自动接收它:
auto pr = some_function();
std::cout << pr.first << ' ' << pr.second;
现在,C++17 标准提供了一种将这对直接解包为单独变量的漂亮方法,如下所示:
auto [x, y] = some_function();
std::cout << x << ' ' << y;
然后是std::minmax_element()
库函数,其中returns一对迭代器。因此,如果我将 vector<int>
传递给此函数,它会返回一对指向向量中最小和最大元素的迭代器。
现在我可以像往常一样接受这些迭代器的一种方法,然后按如下方式取消引用它们。
std::vector<int> v = {4,1,3,2,5};
auto [x, y] = std::minmax_element(v.begin(), v.end());
std::cout << (*x) << ' ' << (*y); // notice the asterisk(*)
现在我的问题是:有没有办法在解包时取消对它们的引用?或者更准确地说,给定以下代码,我可以替换 var1
和var2
使用有效的 C++ 并打印那些迭代器指向的值?
std::vector<int> v = {4,1,3,2,5};
auto [var1, var2] = std::minmax_element(v.begin(), v.end());
std::cout << var1 << ' ' << var2; // notice there is NO asterisk(*)
当然可以。编写一个函数,接受一对可取消引用的事物和 returns 取消引用它们的结果:
template <typename Iterator,
typename R = typename std::iterator_traits<Iterator>::reference>
auto deref(std::pair<Iterator, Iterator> p)
-> std::pair<R, R>
{
return {*p.first, *p.second};
}
然后使用那个函数:
auto [var1, var2] = deref(std::minmax_element(v.begin(), v.end()));
请注意,如果范围为空,则这是 UB,因为您要取消引用结束迭代器两次。
或者,更好:
struct deref_t {
template <typename It,
typename R = typename std::iterator_traits<Iterator>::reference>
friend auto operator|(std::pair<It, It> p, deref_t)
-> std::pair<R, R>
{
return { *p.first, *p.second };
}
};
inline constexpr deref_t deref{};
允许:
auto [var1, var2] = std::minmax_element(v.begin(), v.end()) | deref;