我收到“模板参数推导/替换失败:” 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,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);
}