可变函数中参数的分辨率

时间:2018-05-20 09:29:18

标签: c++ c++11

我试图了解以下代码的作用。特别是函数reverse_binary_value()

我已经阅读了关于可变函数的内容,但我无法理解为什么在返回值时,左移1已完成。

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

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

输入格式

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

x是要比较的值。

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

输出格式

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

示例输入

2 65 1 1 10 0

示例输出

0100000000000000000000000000000000000000000000000000000000000000 0000000000100000000000000000000000000000000000000000000000000000

代码

#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 个答案:

答案 0 :(得分:1)

  

我已经阅读了关于可变函数的内容,但我无法理解为什么在返回值时,左移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>()
  3. reversed_binary_value<1>()对应于非变量template <bool a> int reversed_binary_value() { return a; },因为它与模板参数列表匹配。

    1. a = 1,返回1:
    2. 从递归返回:

      1. 返回1 << 1 + 0等于二进制10,即十进制为2。
      2. 返回10 << 1 + 0等于二进制100,即十进制为4。
      3. 在测试运行期间看它是如何工作的可能很奇怪:

        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;
        ...