Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.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++11_C++14 - Fatal编程技术网

C++ 大量非类型模板参数

C++ 大量非类型模板参数,c++,c++11,c++14,C++,C++11,C++14,我有一些功能对性能非常关键。它们非常通用,除了2个输入外,还依赖于大约12个参数 这些参数是固定的,我有4或5组值(a1..a10)(b1..b10),等等。。。我可以编写函数几次,但为了效率和可维护性,我希望使用非类型模板 想象一下: template <int a, int b, int c, int d, ..., int m> double f(double x, double y) { return a*x+a*b*y+c+d+..+a*x*y; // some

我有一些功能对性能非常关键。它们非常通用,除了2个输入外,还依赖于大约12个参数

这些参数是固定的,我有4或5组值(a1..a10)(b1..b10),等等。。。我可以编写函数几次,但为了效率和可维护性,我希望使用非类型模板

想象一下:

template <int a, int b, int c, int d, ..., int m>
double f(double x, double y) 
{ 
    return a*x+a*b*y+c+d+..+a*x*y; // some very complex math code
}
模板
双f(双x,双y)
{ 
返回a*x+a*b*y+c+d+..+a*x*y;//一些非常复杂的数学代码
}
它仅以以下N种方式使用:

f<1,2,3,...,6>(x,y)
f<4,5,6,...,60>(x,y)
f<10,20,....,50,60>(x,y)
f(x,y)
f(x,y)
f(x,y)
(在库的另一个应用程序中,参数集可能不同,但仍然只有少数)

这一切都很好,但不是很优雅

我正在寻找一些“更好”的方法,以更干净的方式对这些参数进行分组

想法: -创建许多充满constexpr[s]的参数类型 -包含要重写的方法的抽象类(不确定是否可以将其与constexpr..混合使用)

我想知道在boost中是否有其他更好的方法或东西可以很好地解决我的问题

编辑: 类似的东西会很完美!(这显然不起作用)。最重要的是我需要编译时评估

#include <iostream>

struct Params1
{
    constexpr static int a = 2;
    constexpr static double b = 4;
    constexpr static int c = 6;
};

struct Params2
{
    constexpr static int a = 1;
    constexpr static double b = 4.3;
    constexpr static int c = 3;
};

template<P>
double f(double x)
{
    return x*P.a*P.b*P.c;
};


int main() {

    std::cout << f<Params1>(1.2) << std::endl;
    std::cout << f<Params2>(1.2) << std::endl;

    return 0;
}
#包括
结构参数1
{
constexpr static int a=2;
constexpr静态双b=4;
constexpr static int c=6;
};
结构参数2
{
constexpr static int a=1;
constexpr静态双b=4.3;
constexpr static int c=3;
};
模板

双f(双x) { 返回x*P.a*P.b*P.c; }; int main(){


std::cout不确定是否理解您的要求,但

这些参数是固定的,我有4或5组值(a1..a10)(b1..b10),等等

我想您可以使用
std::integer\u序列
并定义4或5种类型

using set1 = std::integer_sequence<int, 1, 2, 3, ....>;
using set2 = std::integer_sequence<int, 2, 4, 6, ....>;
using set3 = std::integer_sequence<int, 10, 20, 30, ....>;
// ...
下面是一个完整的示例(但仅适用于3模板整数)

#包括
#包括
使用set1=std::integer\u序列;
使用set2=std::integer\u序列;
使用set3=std::integer\u序列;
模板
双f(标准::整数序列常数&,双x,双y)
{返回a*(x+y)+b*(x-y)+c*(y-x);}
int main()
{
双x{1.0};
双y{2.0};

std::cout您给定的示例代码运行得很好,只是做了一些小改动。也许这就是您要搜索的内容

struct Params1
{   
    constexpr static int a = 2;
    constexpr static double b = 4;
    constexpr static int c = 6;
};  

struct Params2
{   
    constexpr static int a = 2;
    constexpr static double b = 4;
    constexpr static int c = 6;
};  

template<typename P>
double f(double x)
{   
    return x*P::a*P::b*P::c;
}   


int main() {

    std::cout << f<Params1>(1.2) << std::endl;
    std::cout << f<Params2>(1.2) << std::endl;

    return 0;
}   
struct Params1
{   
constexpr static int a=2;
constexpr静态双b=4;
constexpr static int c=6;
};  
结构参数2
{   
constexpr static int a=2;
constexpr静态双b=4;
constexpr static int c=6;
};  
模板
双f(双x)
{   
返回x*P::a*P::b*P::c;
}   
int main(){
std::cout按如下方式重写
f()
,您的最后一个(后“编辑”)示例应该可以工作

template <typename P>
double f(double x)
{
    return x * P::a * P::b * P::c;
}
模板
双f(双x)
{
返回x*P::a*P::b*P::c;
}
要点是

(a) 使用
模板更改
模板


(b) 并使用
p::a
p::b
p::c
(类型中的静态值)而不是
p.a
p.b
p.c
(对象的值)

谢谢max66。这会起作用,但我必须使用索引。代码看起来会比它应该的更复杂。我希望继续为每个参数使用名称。关键点是:我需要编译时求值和清理names@purpletentacle-inside
f()
您可以使用名称(
a
b
c
,…)@purpletentacle-答案修改为减少的(仅3个模板整数)例如,谢谢。我在玩ideaYes,我想知道是否有某种方法可以创建一个抽象类,让库用户清楚typename P应该是什么样子。只是想知道是否有更好的方法。是的,我写得很快。这是最初的想法,但我在寻找更好的方法。@PurpleteTaple-问题是
double
值不能作为模板值;如果只有integer,
P
可以作为模板类,您可以使用
P
复制
std::integer\u序列
解决方案;如果使用
double
值,我能想象的最好的情况是类内的
静态constexpr
值(使用起来不太方便).我会接受这个的.我感谢你为帮助我所做的努力!谢谢!
#include <utility>
#include <iostream>

using set1 = std::integer_sequence<int, 1, 2, 3>;
using set2 = std::integer_sequence<int, 2, 4, 6>;
using set3 = std::integer_sequence<int, 10, 20, 30>;

template <int a, int b, int c>
double f(std::integer_sequence<int, a, b, c> const &, double x, double y)
 { return a*(x+y)+b*(x-y)+c*(y-x); }

int main ()
 {
   double x { 1.0 };
   double y { 2.0 };

   std::cout << f(set1{}, x, y) << std::endl; // print 4
   std::cout << f(set2{}, x, y) << std::endl; // print 8
   std::cout << f(set3{}, x, y) << std::endl; // print 40
 }
struct Params1
{   
    constexpr static int a = 2;
    constexpr static double b = 4;
    constexpr static int c = 6;
};  

struct Params2
{   
    constexpr static int a = 2;
    constexpr static double b = 4;
    constexpr static int c = 6;
};  

template<typename P>
double f(double x)
{   
    return x*P::a*P::b*P::c;
}   


int main() {

    std::cout << f<Params1>(1.2) << std::endl;
    std::cout << f<Params2>(1.2) << std::endl;

    return 0;
}   
template <typename P>
double f(double x)
{
    return x * P::a * P::b * P::c;
}