问题描述
#include <iostream>
using namespace std;
// Enter your code for reversed_binary_value<bool...>()
int reversed_binary_value()
{
return 0;
}
template <bool i,bool... arg>
int reversed_binary_value()
{
int z=0;
z=reversed_binary_value(arg...)*2;
if(i==0)
return z;
else
return z+1;
}
template <int n,bool...digits>
struct CheckValues {
static void check(int x,int y)
{
CheckValues<n-1,digits...>::check(x,y);
CheckValues<n-1,1,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";
}
}
我收到“没有匹配函数调用'reversed_binary_value(bool,bool,bool,bool,bool)”,然后“模板参数推导/替换失败:” 该代码是针对https://www.hackerrank.com/challenges/cpp-variadics/problem上的问题的,因此我无法更改锁定的代码
解决方法
您的代码中的错误正在调用reversed_binary_value()
z=reversed_binary_value(arg...)*2;
期望布尔值带有 template 参数。
所以您必须按以下方式调用它
z=reversed_binary_value<arg...>()*2;
// ....................^......^^^
但是现在您遇到了另一个问题:当可变参数包args...
为空时,调用变为
z=reversed_binary_value<>()*2;
因此,当您的终端<>
函数时,您无需模板参数即可显式调用模板函数(reverse_binary_value()
)
int reversed_binary_value()
{
return 0;
}
不是模板。
我建议您使用一个肮脏但有用的技巧:在模板函数中转换终端版本,以接受不同于值(可能是类型)且带有默认参数的内容;例如
template <typename = void>
int reversed_binary_value()
{
return 0;
}
这样最终的空列表调用
z=reversed_binary_value<>()*2;
匹配reverse_binary_value<void>()
。
@ max66答案的另一种选择是使用enable_if
来禁用特殊单参数情况的递归版本。这样可以明确地用另一个模板重载该函数:
template<bool b>
int reversed_binary_value()
{
return b?1:0;
}
template <bool i=1,bool... arg>
std::enable_if_t<sizeof...(arg) != 0,int>
reversed_binary_value()
{
int z=0;
z=reversed_binary_value<arg...>()*2;
if(i==0)
return z;
else
return z+1;
}
如果您想看中C ++ 17折叠表达式,这是三行解决方案:
template<bool...Args>
constexpr int reversed_binary_value(){
int res=0,tmp=0;
(tmp|=...|=((res*=2)+=Args));
return res;
}
int main()
{
static_assert(reversed_binary_value<1,1,1>()==15);
static_assert(reversed_binary_value<0,1>()==10);
static_assert(reversed_binary_value<1,1>()==9);
}