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++ 放宽枚举类和布尔模板参数的constexpr要求_C++_Templates - Fatal编程技术网

C++ 放宽枚举类和布尔模板参数的constexpr要求

C++ 放宽枚举类和布尔模板参数的constexpr要求,c++,templates,C++,Templates,考虑代码,其中有一个函数累加,它执行繁重的调度程序函数过程。累积函数在热循环中测试参数,因此该参数是模板化的 enum类Op{ 乘 添加 }; 样板 整数累加(常数std::vector和vec){ INTA=op==op::乘法?1:0; 用于(INTV:vec) 如果constexpr(op==op::Add)a+=v;否则a*=v; 返回a; } int进程(const std::vector&vec,Op){ 收益累加(vec); } 您可能已经注意到,由于从进程传递的模板参数不是co

考虑代码,其中有一个函数
累加
,它执行繁重的调度程序函数
过程
。累积函数在热循环中测试参数,因此该参数是模板化的

enum类Op{
乘
添加
};
样板
整数累加(常数std::vector和vec){
INTA=op==op::乘法?1:0;
用于(INTV:vec)
如果constexpr(op==op::Add)a+=v;否则a*=v;
返回a;
}
int进程(const std::vector&vec,Op){
收益累加(vec);
}
您可能已经注意到,由于从进程传递的模板参数不是constexpr,所以此代码不会编译。但是,当模板参数是bool,尤其是enum类时,没有理由不编译它

这样的代码在实践中经常出现,当一个执行繁重工作的函数有几个变体时(我们只想在代码库中保留一个副本)。是否有建议或讨论使此类代码在未来有效

(C++有太多的特性,尽管我需要的一个特性缺失了:p)

但是,当模板参数是bool,尤其是enum类时,没有理由不编译它

当参数是值很少的
bool
enum
时,没有任何东西禁止您选择带有
if
开关的情况

int process1 (const std::vector<int> &vec, bool b) {
  if ( b == true )
     return accumulate<true>(vec);
  else
     return accumulate<false>(vec);
}


int process2 (const std::vector<int> &vec, Op op) {
  switch ( op ) {
     case Op::Multiply:
        return accumulate<Op::Multiply>(vec);
        break;

     case Op::Add:
        return accumulate<Op::Add>(vec);
        break;

     // other cases

     // default
  }
} 
int process1(const std::vector&vec,bool b){
如果(b==true)
收益累加(vec);
其他的
收益累加(vec);
}
int process2(const std::vector&vec,Op){
开关(op){
案例Op::乘法:
收益累加(vec);
打破
案例Op::添加:
收益累加(vec);
打破
//其他情况
//违约
}
} 

但是,当模板参数是bool,尤其是枚举类时,没有理由不进行编译。
有,
op
不是编译时间常数。类型一点也不重要。@tkausl当它是枚举类或布尔时,编译器1)知道所有的可能性。2) 它们只有很少。这就足够编译代码了。对于允许枚举的问题,有一个建议是,您可以生成枚举中不存在的枚举值。即使对于枚举类也是如此。查看
std::byte
。您可以执行
std::byte foo{42}
,即使
std::byte
没有枚举。谢谢!这就是代码库当前的样子。我认为这是一种非常常见的情况,尤其是在api服务的上下文中:传入的请求中有各种参数,为了加快实现速度,我们对实现进行了模板化。如果这个开关调度可以卸载到编译器中,那就太好了。开关块是乏味的,也是许多小错误的根源。再添加一种请求,在开关块中添加一个新条目,但是你忘记了break语句,glhf@boinkboink-对于当前语言,我知道的唯一替代方法是将
op
值嵌入
std::integral_常量
;因此,该值可以作为函数的参数传递,不同的
op
值将成为不同的类型。@boinkboink:可能会出现缺少中断、缺少开关大小写的警告。但即使使用
std::integral\u常量
,也应该完成从运行时值到编译时值的转换/分派。@Jarod42-Oh,是:我在考虑使用
std::integral_constant
以防
op
值是
process()的调用方已知的编译时(模板参数或
constepr
值)。