C++ 元组是一个容器,可以在其中存储多种类型的多个值。我们可以使用std::get()访问元组的元素,但std::get()始终采用常量变量参数,因此我们不能简单地使用循环遍历它。对于需要遍历元组所有元素的任务。喜欢打印所有元素。
下面是说明迭代元素元组的程序:
CPP14
// C++ program to iterate over the
// elements of an std::tuple
// using std:get()
#include
#include
#include
// Driver Code
int main()
{
// Declare a tuple and initialize
// it using its constructor
std::tuple
tup("Geeks", "for", "Geeks");
std::cout << "Values of tuple: ";
// std::get is used to access
// the value of tuple.
std::cout << std::get<0>(tup)
<< " " << std::get<1>(tup)
<< " " << std::get<2>(tup)
<< std::endl;
// Make the tuple using
// std::make_tuple function
tup = std::make_tuple("Hey", "Welcome to",
"Geeksforgeeks");
// Print tuple
std::cout << "Values of tuple(Modified): ";
std::cout << std::get<0>(tup) << " "
<< std::get<1>(tup) << " "
<< std::get<2>(tup)
<< std::endl;
return 0;
}
CPP
// C++ program to iterated thorough
// all values. I equals number
// of values in tuple
#include
#include
#include
using namespace std;
// Function to iterate through all values
// I equals number of values in tuple
template
typename enable_if::type
printTuple(tuple tup)
{
// If iterated through all values
// of tuple, then simply return.
return;
}
template
typename enable_if<(I < sizeof...(Ts)),
void>::type
printTuple(tuple tup)
{
// Print element of tuple
cout << get(tup) << " ";
// Go to next element
printTuple(tup);
}
// Driver Code
int main()
{
// Creating the tuple
tuple tup("Geeks",
"for",
"Geeks");
// Function call
printTuple(tup);
return 0;
}
CPP
// C++ program to iterated thorough
// all values. I equals number
// of values in tuple
#include
#include
#include
using namespace std;
// WARNING: C++17 or above required
template
contexpr void printTuple(tuple tup)
{
// If we have iterated through all elements
if
constexpr(I == sizeof...(Ts))
{
// Last case, if nothing is left to
// iterate, then exit the function
return;
}
else {
// Print the tuple and go to next element
cout << get(tup) << " ";
// Going for next element.
printTuple(tup);
}
}
// Driver Code
int main()
{
// Initialize the tuple
tuple tup("Geeks",
"for",
"Geeks");
// Function call
printTuple(tup);
return 0;
}
CPP
// C++ program to iterated thorough
// all values. I equals number
// of values in tuple
#include
#include
#include
template
void printTuple(std::tuple tup)
{
// Getting size of tuple
std::size_t length = sizeof...(Ts);
// Using std::apply to print elements
std::apply(
// A lambda function
[length](auto const&... ps) {
std::cout << "[ ";
int k = 0;
// Variadic expansion used.
((std::cout << ps
<< (++k == length ? "" : "; ")),
...);
std::cout << " ]";
},
tuple);
}
// Driver Code
int main()
{
// Initialize the tuple
std::tuple
tup("Geeks", "for", "geeks");
// Function call
printTuple(tup);
return 0;
}
Values of tuple: Geeks for Geeks
Values of tuple(Modified): Hey Welcome to Geeksforgeeks
当我们尝试遍历整个元组时,问题就出现了。因此,我们在这里有两种方法来遍历元组的值:
- 使用可变模板和元编程(不使用 std::apply)。
- 使用可变模板和 std::apply。
使用可变模板和模板:
可变模板用于传递打包在一个模板参数中的多个参数,并且可以稍后在函数内部扩展。下面是我们将如何遍历元组的所有元素。
下面是相同的实现:
CPP
// C++ program to iterated thorough
// all values. I equals number
// of values in tuple
#include
#include
#include
using namespace std;
// Function to iterate through all values
// I equals number of values in tuple
template
typename enable_if::type
printTuple(tuple tup)
{
// If iterated through all values
// of tuple, then simply return.
return;
}
template
typename enable_if<(I < sizeof...(Ts)),
void>::type
printTuple(tuple tup)
{
// Print element of tuple
cout << get(tup) << " ";
// Go to next element
printTuple(tup);
}
// Driver Code
int main()
{
// Creating the tuple
tuple tup("Geeks",
"for",
"Geeks");
// Function call
printTuple(tup);
return 0;
}
Geeks for Geeks
使用 constexpr()函数和 if constexpr 表达式大大简化了这种情况,但仅从 C++17 开始可用。我也为此简化了代码,您可以在 C++17 中运行它。
下面是上述方法的实现:
CPP
// C++ program to iterated thorough
// all values. I equals number
// of values in tuple
#include
#include
#include
using namespace std;
// WARNING: C++17 or above required
template
contexpr void printTuple(tuple tup)
{
// If we have iterated through all elements
if
constexpr(I == sizeof...(Ts))
{
// Last case, if nothing is left to
// iterate, then exit the function
return;
}
else {
// Print the tuple and go to next element
cout << get(tup) << " ";
// Going for next element.
printTuple(tup);
}
}
// Driver Code
int main()
{
// Initialize the tuple
tuple tup("Geeks",
"for",
"Geeks");
// Function call
printTuple(tup);
return 0;
}
输出:
下面是上面代码的输出:
解释:
std::get()的要求是一个常量索引,没有变量。我们总是可以为模板函数指定一个常数,这里的“I”是函数的常数。因此,我们将有 n+1 个print_num()函数的实例化,其中 n 是元组的大小,每个实例都有“I”作为其自身的常数。所以这些函数的实例化会像print_tuple、print_tuple、….、print_tuple,所有这些函数都会被依次调用。这是模板元编程
注意:因此,您不能在 Geeksforgeeks IDE 上运行上述代码,您需要在另一个编译器上运行它。如果你想使用 C++14 或 C++11,你可以使用第一种方法。元组和模板仅在 C++11 中可用,因此不能使用旧版本。
使用可变模板和 std::apply() :
- 首先,关于std::get()是什么的简单指南。 std::get()在元组元素上实现一些函数,将元组元素视为该函数的值。它接受一个函数f(x, y, z….) 和一个元组 (x, y, z…) 作为函数的参数,并返回 f 返回的值。
- 现在还有一两件事,关于可变参数的扩展,如果我们需要申请一个可变参数模板的所有值的一些函数,那么我们就做类似foo(TS)…,其中Ts是我们的可变参数模板,和Foo()是函数需要应用于打包在 Ts 中的所有值。这里函数“…”后的三个点表示该函数应用于可变参数模板的扩展。
- Lambda 函数是匿名函数,可以轻松声明和应用。它们的实现方式如下:
[&a, b, c] (int x, float &y) {
// Function Body
}
- 这里x和y为参数,其中x是通过和y值传递通过引用的函数。而且,x、y 和 z 是将在函数内部出于某种目的使用的变量,因此它们被馈送到函数,这意味着它们将在函数的范围内可用。
下面是相同的实现:
CPP
// C++ program to iterated thorough
// all values. I equals number
// of values in tuple
#include
#include
#include
template
void printTuple(std::tuple tup)
{
// Getting size of tuple
std::size_t length = sizeof...(Ts);
// Using std::apply to print elements
std::apply(
// A lambda function
[length](auto const&... ps) {
std::cout << "[ ";
int k = 0;
// Variadic expansion used.
((std::cout << ps
<< (++k == length ? "" : "; ")),
...);
std::cout << " ]";
},
tuple);
}
// Driver Code
int main()
{
// Initialize the tuple
std::tuple
tup("Geeks", "for", "geeks");
// Function call
printTuple(tup);
return 0;
}
- 输出:
下面是上面代码的输出:
注意: std::apply()仅在 C++17 中可用。所以,你不能在 Geeksforgeeks IDE 上运行这段代码,你需要在另一个编译器上运行它。如果你想使用 C++14 或 C++11,你可以使用第一种方法。元组和模板仅在 C++11 中可用,因此不能使用旧版本。