C++ 打开模板参数以提高类型安全性的有效性
我有一个函数,它将枚举值和其他组合值作为参数。根据枚举的值,该函数以不同的方式操纵其他参数。我知道函数不能用一个或多个潜在的枚举值调用。例如:C++ 打开模板参数以提高类型安全性的有效性,c++,templates,types,enums,compiler-warnings,C++,Templates,Types,Enums,Compiler Warnings,我有一个函数,它将枚举值和其他组合值作为参数。根据枚举的值,该函数以不同的方式操纵其他参数。我知道函数不能用一个或多个潜在的枚举值调用。例如: enum class Colour { RED, GREEN, BLUE, BLACK}; // Pre: colour != Colour::BLACK void do_thing_assuming_nonblack_colour(Colour colour, /*other args*/) { assert(colour != Colour
enum class Colour { RED, GREEN, BLUE, BLACK};
// Pre: colour != Colour::BLACK
void do_thing_assuming_nonblack_colour(Colour colour, /*other args*/) {
assert(colour != Colour::BLACK);
switch (colour) {
case Colour::RED: // do thing A
case Colour::GREEN: // do thing B
case Colour::BLUE: // do thing C
}
}
在编译时,我得到一个编译器警告,因为我没有显式处理color==color::BLACK
案例。为了安抚编译器,我必须包含类似于default://这永远不会发生
一位同事建议在color
上设置模板,因为它允许编译器静态地确定从未使用无效的枚举值调用函数模板:
template<Colour colour>
void do_thing_assuming_nonblack_colour(/*other args*/) {
switch (colour) {
case Colour::RED: // do thing A
case Colour::GREEN: // do thing B
case Colour::BLUE: // do thing C
}
}
模板
void do\u thing\u假设颜色为非黑色(/*其他参数*/){
开关(彩色){
外壳颜色::红色://做一件事
外壳颜色:绿色://做某事B
外壳颜色::蓝色://做事情C
}
}
在编译时,编译器将在实例化do\u thing\u假设颜色为非黑色(…)
时发出警告,因为这种情况不在开关情况下处理。我们可以通过static\u assert
更严格地执行这一点。然而,在我看来,这似乎是滥用模板参数,因为从逻辑上讲,枚举是函数的一个参数,而且开关情况基本上变得无用,因为每个枚举值现在完全由一个单独的函数处理。因此,在每个函数中,只有一种情况会触发
这是推荐(或至少有效)使用的模板参数吗?如您所观察到的,如果您将颜色
作为
函数做某事\u假设非黑色\u颜色
而非黑色
运行时函数参数,无论何时编写对
做事情\u假设非黑色\u颜色
它只能做事情
这是您在编译代码之前决定的。
如果有时从文件F的第N行执行函数调用
将对象涂成红色,然后执行该函数调用始终将对象涂成红色
如果您从内部调用do\u thing\u假设颜色为非黑色
具有签名的函数,如
void做更复杂的事情(颜色)
,
您需要单独呼叫do\u thing\u successing\u non black\u color
要处理可能传递给的每种颜色,请执行更复杂的操作
。
或者你也可以为它编写专门的模板
做更复杂的事情
,但你很快就会发现
如果沿着这条路走得很远,就会出现大量重复代码,
使维护这个代码库成为噩梦
但是如果你能接受颜色
参数
假设在编译时必须始终知道非黑色颜色,则,
您可以使用模板专门化消除switch语句:
template <Colour> void do_thing_assuming_nonblack_colour();
template <> void do_thing_assuming_nonblack_colour<Colour::RED>() {
// do thing A
}
template <> void do_thing_assuming_nonblack_colour<Colour::GREEN>() {
// do thing B
}
template <> void do_thing_assuming_nonblack_colour<Colour::BLUE>() {
// do thing C
}
template void do_thing_假设非黑色颜色();
模板无效做某事假设非黑色颜色(){
//做事
}
模板无效做某事假设非黑色颜色(){
//做B件事
}
模板无效做某事假设非黑色颜色(){
//做C件事
}
除了不需要开关
,这种设计还确保
调用void do\u thing\u假设颜色为非黑色()
不仅会引起编译器警告;
它将导致编译时错误,
为您提供更好的保护,防止意外伤害
使用参数color::BLACK
调用此函数将运行时开关与编译时机制混合使用没有多大意义。你在实践中如何使用这个东西?你将用do\u thing\u suggestion\u nonblack\u color(color::RED,…)
替换do\u thing\u suggestion\u nonblack\u color(…)
等等作为其他枚举值。是的,但是你如何决定调用哪个函数模板实例化?我不确定我是否理解你的问题。。。无论你想做什么,你都可以打电话给合适的人。如果你把一个形状涂成蓝色,你会叫color\u shape(形状)
。