【发布时间】:2015-02-22 16:35:22
【问题描述】:
我有一个函数,它接受一个枚举值和其他分类值作为参数。根据枚举的值,该函数以不同的方式操作其他参数。我知道这个函数不能用一个或多个潜在的枚举值调用。例如:
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
}
}
在编译时,我收到编译器警告,因为我没有明确处理 colour == Colour::BLACK 情况。为了安抚编译器,我必须包含 default: // this never happens 之类的内容。
一位同事建议在 Colour 上进行模板化,因为它允许编译器静态确定函数模板永远不会使用无效的枚举值调用:
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
}
}
在编译时,编译器会在 do_thing_assuming_nonblack_colour<Colour::BLACK>(...) 的实例化时发出警告,因为这种情况在 switch-case 中没有处理。我们可以使用static_assert 更严格地执行此操作。然而,对我来说,这似乎是对模板参数的滥用,因为从逻辑上讲,枚举是函数的参数,此外,switch case 基本上变得无用,因为每个枚举值现在完全由一个单独的函数处理。所以在每个函数中,只有一种情况会触发。
这是推荐(或至少有效)使用的模板参数吗?
【问题讨论】:
-
将运行时开关与编译时机制混合使用没有多大意义。你会如何在实践中使用这个东西?
-
对于其他枚举值,您可以将
do_thing_assuming_nonblack_colour(Colour::RED, ...)替换为do_thing_assuming_nonblack_colour<Colour::RED>(...),依此类推。 -
是的,但是您将如何决定调用哪个函数模板实例化?
-
我不确定我是否理解你的问题......你打电话给适合你想要做的任何事情的任何一个。如果您将形状着色为蓝色,您可以调用
colour_shape<Colour::BLUE>(shape)。
标签: c++ templates types enums compiler-warnings