可变参数函数中参数的解析

Resolution of parameters in variadic function

本文关键字:参数 函数 变参      更新时间:2023-10-16

我试图理解以下代码在做什么。特别是功能reverse_binary_value()

我读过关于可变参数函数的信息,但我不明白为什么在返回值时,左移 1 完成了。

我在hackerank上得到了这些代码。问题是这样的

创建一个名为 reversed_binary_value 的模板函数。它必须采用任意数量的布尔值作为模板参数。这些布尔值以相反的顺序表示二进制数字。您的函数必须返回一个整数,该整数对应于布尔值所表示的数字的二进制值。例如:reversed_binary_value<0,0,1>(( 应返回 4。

输入格式

第一行包含一个整数,即测试用例的数量。后续的每一行都包含一个测试用例。测试用例分别描述为空格分隔的整数和。

x 是要比较的值。

y表示要比较的范围:64*y 到 64*y+63

输出格式

每行输出包含 64 个二进制字符。(即 0 和 1(。每个字符表示范围中的一个值。第一个字符对应于区域中的第一个值。最后一个字符对应于区域中的最后一个值。如果范围内的值与 X 匹配,则字符为 1;否则,字符为 0。

示例输入

阿拉伯数字 65 1 10 0

示例输出

010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000

法典

#include <iostream>
using namespace std;
template <bool a> int reversed_binary_value() { return a; }
template <bool a, bool b, bool... d> int reversed_binary_value() {
return (reversed_binary_value<b, d...>() << 1) + a;
}
template <int n, bool...digits>
struct CheckValues {
static void check(int x, int y)
{
CheckValues<n-1, 0, digits...>::check(x, y);
CheckValues<n-1, 1, digits...>::check(x, y);
}
};
template <bool...digits>
struct CheckValues<0, digits...> {
static void check(int x, int y)
{
int z = reversed_binary_value<digits...>();
std::cout << (z+64*y==x);
}
};
int main()
{
int t; 
std::cin >> t;
for (int i=0; i!=t; ++i) {
int x, y;
cin >> x >> y;
CheckValues<6>::check(x, y);
cout << "n";
}
}

我读过关于可变参数函数的信息,但我不明白为什么在返回值时,左移 1 完成了。

template <bool a, bool b, bool... d> int reversed_binary_value() {
return (reversed_binary_value<b, d...>() << 1) + a;
}

想象一下,您有该示例<0,0,1>。它对应于100,十进制为4。此函数是一个递归模板,在第一次迭代中,a 表示最低有效位,在第二次迭代中,它表示下一个有效位。为了正确形成值,reversed_binary_value<b, d...>()的结果必须在每次迭代期间向左移动一位。

通过迭代:

  1. a = 0 , 调用reversed_binary_value<0,1>()
  2. a = 0 , 调用reversed_binary_value<1>()

reversed_binary_value<1>()对应于非可变参数template <bool a> int reversed_binary_value() { return a; },因为它与模板参数列表匹配。

  1. a = 1 ,返回 1:

从递归返回:

  1. 返回1 << 1 + 0等于二进制10,即十进制中的 2。
  2. 返回10 << 1 + 0等于二进制100,即十进制中的4。

在测试运行期间看看它是如何工作的可能很好奇:

template <bool a> int reversed_binary_value() {
cerr << "a = " << a << ";n";
return a;
}
template <bool a, bool b, bool... d> int reversed_binary_value() {
cerr << "a = " << a << " b = " << b << " d = ";
(cerr << ... << d);  // C++14
cerr <<";n";
return (reversed_binary_value<b, d...>() << 1) + a;
}

在 stderr(流 #2(上的输出,请注意,cerrcout可能不同步,因此输出到cout的顺序可能不同步。

a = 0 b = 0 d = 0000;
a = 0 b = 0 d = 000;
a = 0 b = 0 d = 00;
a = 0 b = 0 d = 0;
a = 0 b = 0 d = ;
a = 0;
a = 1 b = 0 d = 0000;
a = 0 b = 0 d = 000;
a = 0 b = 0 d = 00;
a = 0 b = 0 d = 0;
a = 0 b = 0 d = ;
a = 0;
a = 0 b = 1 d = 0000;
a = 1 b = 0 d = 000;
a = 0 b = 0 d = 00;
a = 0 b = 0 d = 0;
a = 0 b = 0 d = ;
a = 0;
...