Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;可变模板推断失败_C++_Templates - Fatal编程技术网

C++ C++;可变模板推断失败

C++ C++;可变模板推断失败,c++,templates,C++,Templates,我已经编写了一个带有递归求值的可变模板函数。对于最后一个参数,我在没有变量包的情况下实现了一个专门化,并且一切正常 现在我想把可变函数参数转换成模板参数 这是我的尝试: template<typename N, int p> // specialization N constexpr myadd(const N &n) { return n + p; } template<typename N, int p, int ... v> // variadic

我已经编写了一个带有递归求值的可变模板函数。对于最后一个参数,我在没有变量包的情况下实现了一个专门化,并且一切正常

现在我想把可变函数参数转换成模板参数

这是我的尝试:

template<typename N, int p> // specialization
N constexpr myadd(const N &n)
{
    return n + p;
}

template<typename N, int p, int ... v> // variadic
N constexpr myadd(const N &n)
{
    return myadd<N, v...>(n) + p;
}

int testfun()
{
    return myadd<int, 2>(7);
}
模板//专门化
N constexpr myadd(const N&N)
{
返回n+p;
}
模板//变量
N constexpr myadd(const N&N)
{
返回myadd(n)+p;
}
int testfun()
{
返回myadd(7);
}
gcc和clang报告了一个不明确的重载,无法使用空参数包决定“专门化”和“变量”


我尝试删除专门化并检查变量模板中的数据包大小,但是没有专门化编译器无法推断参数“p”

参数包确实可能是空的。通过更改专门化以处理不添加任何内容的情况,可以避免歧义:

template<typename N> // specialization
N constexpr myadd(const N &n)
{
    return n;
}

template<typename N, N p, N ... v> // variadic
N constexpr myadd(const N &n)
{
    return myadd<N, v...>(n) + p;
}
模板//专门化
N constexpr myadd(const N&N)
{
返回n;
}
模板//变量
N constexpr myadd(const N&N)
{
返回myadd(n)+p;
}
使用C++17,您可以通过以下方式简化此过程:

template//variadic
N constexpr myadd(const N&N)
{
返回(v+…+n);
}
如中所述,可变数据包实际上可能是空的。 但是你可以专门处理非空变量包的情况

例如:

#include <iostream>
#include <type_traits>

template<typename N, int p> // specialization
N constexpr myadd(const N &n)
{
    std::cout << "specialization" << std::endl;
    return n + p;
}

template<typename N, int p, int ... v, class = std::enable_if_t<(sizeof...(v) > 0)>> // variadic
N constexpr myadd(const N &n)
{
    std::cout << "variadic" << std::endl;
    return myadd<N, v...>(n) + p;
}

int main()
{
    std::cout <<  myadd<int, 2>(7) << std::endl;
    std::cout <<  myadd<int, 2, 4>(7) << std::endl;
    
    return 0;
}
#包括
#包括
模板//专门化
N constexpr myadd(const N&N)
{

std::这是很好的建议,但对于实际算法,没有简单的方法来更改它以适合您的代码。我使用@francesco的解决方案。实际算法有什么不同?您可以在这里找到我的原始算法:。我想用给定的因子计算“n”以上的最小整数(以确定理想的FFT大小)但是,该算法将这些值作为函数参数传递,而不是作为模板参数,并且将编译得很好。尽管如此,我可以看到折叠表达式是如何不合适的。@ G-SLIPEN:这正是我的意思。参数是内联的。将其与我使用的分区进行比较。因此,如果编译器考虑的话,这将是一个巨大的优势。s是固定值。请注意,没有专门化,只有不同的重载。或者
template N constexpr myadd(const N&);
没有SFINAE。
#include <iostream>
#include <type_traits>

template<typename N, int p> // specialization
N constexpr myadd(const N &n)
{
    std::cout << "specialization" << std::endl;
    return n + p;
}

template<typename N, int p, int ... v, class = std::enable_if_t<(sizeof...(v) > 0)>> // variadic
N constexpr myadd(const N &n)
{
    std::cout << "variadic" << std::endl;
    return myadd<N, v...>(n) + p;
}

int main()
{
    std::cout <<  myadd<int, 2>(7) << std::endl;
    std::cout <<  myadd<int, 2, 4>(7) << std::endl;
    
    return 0;
}