Как у вас может быть несколько строк или операторов внутри расширения пакета C++?
Предположим, у меня есть простой код, подобный приведенному ниже, который просто печатает все значения в кортеже и отслеживает текущую итерацию.
#include <iostream>
#include <tuple>
#include <utility>
using std::cout;
int main() {
std::tuple<int, double, size_t, unsigned, short, long long, long> my_tuple(7, 4, 1, 8, 5, 2, 9);
//Can you spot the pattern? :)
std::apply(
[](auto&&... current_value) {
size_t i = 0; //This is only executed once
((
cout << i++ << ", " << current_value << "\n" //This is repeated the length of the tuple
), ...);
}, my_tuple
);
return 0;
}
Если бы я хотел, например, распечатать значение кортежа, только если индекс был больше 2, как я мог бы это сделать? Я не могу просто поставить
if
перед
cout
потому что заявления не разрешены (получил
[cquery] expected expression
на ответ).
В более общем плане, как я могу делать такие вещи, как несколько строк кода или операторов в расширении пакета?
Использование лямбды внутри работает, например
std::apply(
[](auto&&... current_value) {
size_t i = 0;
((
[¤t_value, &i](){
cout << i << ", " << current_value << "\n";
++i;
}()
), ...);
}, my_tuple
);
Но я не могу представить, что это наиболее эффективное (или предполагаемое) решение.
1 ответ
Он читается намного лучше, если вы объявляете лямбду отдельно, а затем свертываетесь, вызывая ее:
auto f = [&](auto& value){
cout << i << ", " << value << "\n";
++i;
};
(f(current_value), ...);
Вы также можете использовать что-нибудь Boost.Mp11's
tuple_for_each
чтобы избежать слоя косвенного обращения:
size_t i = 0;
tuple_for_each(my_tuple, [&](auto& value){
cout << i << ", " << value << "\n";
++i;
});
это гораздо более прямой способ сделать это, чем пройти через
std::apply
. Даже если вы не хотите использовать Boost.Mp11 (а должны захотеть), это довольно легко реализовать.
Было предложение языка для так называемых операторов расширения, которые сделали бы эту языковую функцию первоклассной. Это не совсем для C++20, но могло быть и на C++23:
size_t i = 0;
template for (auto& value : my_tuple) {
cout << i << ", " << value << "\n";
++i;
}