我收到“模板参数 deduction/substitution 失败:”C++ 错误

I am getting " template argument deduction/substitution failed:" Error in C++

我有一个 C++ 代码如下:

#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, 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";
    }
}

我得到“没有匹配函数来调用‘reversed_binary_value(bool, bool, bool, bool, bool)”,然后是“模板参数 deduction/substitution 失败:” 此代码用于 https://www.hackerrank.com/challenges/cpp-variadics/problem 上的问题,因此我无法更改锁定的代码

您的代码中的错误是调用 reversed_binary_value()

z=reversed_binary_value(arg...)*2;

期望布尔值是一个 模板 参数。

所以你必须这样调用它

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 禁用特殊 one-parameter 情况下的递归版本。这允许使用另一个模板明确地重载函数:

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 倍表达式,这里是 three-line 解决方案:

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,1>()==15);
    static_assert(reversed_binary_value<0,1,0,1>()==10);
    static_assert(reversed_binary_value<1,0,0,1>()==9);
}