我有来自这里的代码:
std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
return get<0>(t1) < get<0>(t2); // or use a custom compare function
});
Run Code Online (Sandbox Code Playgroud)
我想多次排序元组,所以我编写了这段代码:
int k = 10;
while(k--){
std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
return get<k>(t1) < get<k>(t2); // or use a custom compare function
});
}
Run Code Online (Sandbox Code Playgroud)
但我得到错误error: ‘k’ is not captured.我试着这样做:
int k = 10;
while(k--){
std::sort(begin(v), end(v), [&k](auto const &t1, auto const &t2) {
return get<k>(t1) < get<k>(t2); // or use a custom compare function
});
}
Run Code Online (Sandbox Code Playgroud)
但它不是正确的方法和错误error: the value of ‘k’ is not usable in a constant expression发生.
如何捕获k变量?
正如mch在评论中所说,问题在于它k不是编译时常量.
对于编译时常量,要迭代N到0,您可能需要模板和递归:
#include <algorithm>
#include <tuple>
#include <type_traits>
#include <vector>
using namespace std; // just for simplify, and not recommended in practice
template <size_t N, typename Iterator, enable_if_t<N == 0, int> = 0>
void foo(Iterator begin, Iterator end)
{
sort(begin, end,
[](const auto &t1, const auto &t2) {
return get<0>(t1) < get<0>(t2);
}
);
}
template <size_t N, typename Iterator, enable_if_t<N != 0, int> = 0>
void foo(Iterator begin, Iterator end)
{
sort(begin, end,
[](const auto &t1, const auto &t2) {
return get<N>(t1) < get<N>(t2);
}
);
foo<N - 1>(begin, end);
}
int main()
{
vector<tuple<int, int>> v{{0, 1}, {0, 0}, {1, 1}};
foo<1>(v.begin(), v.end());
// posible results:
// {0, 0}, {0, 1}, {1, 1}
// {0, 1}, {0, 0}, {1, 1} // impossible if use std::stable_sort instead
}
Run Code Online (Sandbox Code Playgroud)
std::get只接受模板参数,该参数是一个可以在编译时计算其值的表达式。您不能使用k,因为它是一个会更改值的变量。
std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
const int k = 3;
return std::get<k>(t1) < std::get<k>(t2); // or use a custom compare function
});
Run Code Online (Sandbox Code Playgroud)
正如我在评论中所写,我知道const int = 3会隐藏klambda 表达式之外的值,但这个示例表明,get当它收到编译时间常量值时,它将起作用。例如,如果您尝试设置k = 5,例如 wherev只有 4 个元组参数,编译器将给出错误,因为它知道这超出了范围。
下面的代码会报错,但是如果k设置为3就可以了
std::vector<std::tuple<int, int, int, int>> v;
std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
const int k = 5;
return std::get<k>(t1) < std::get<k>(t2); // or use a custom compare function
});
Run Code Online (Sandbox Code Playgroud)