template<typename T>
void
unused(T const &) {
/* Do nothing. */
}
int main() {
volatile bool x = false;
unused(!x); // type of "!x" is bool
}
如下所述,g++ v3.4.6编译器报错:
test.cc: In constructor `test::test()':
test.cc:11: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
test.cc:3: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
这里的目标是在优化后的代码中消除未使用的变量警告。我有一个宏来进行断言检查,但在优化后的代码中,该断言会消失,但我希望断言表达式中的任何变量仍然保持引用,以便我不仅在优化后的代码中获得未使用变量的警告。在unused()模板函数的定义中,我使用引用,以便不会无意中运行复制构造函数代码,从而使对unused的调用可以被编译器完全省略。
对于那些感兴趣的人,断言宏看起来像这样:
#ifdef NDEBUG
# define Assert(expression) unused(expression)
#else // not NDEBUG
# define Assert(expression) \
{ \
bool test = (expression); \
\
if (!test) { \
if (StopHere(__LINE__, __FILE__, __PRETTY_FUNCTION__, \
#expression, false)) { \
throw Exit(-1); /* So that destructors are run. */ \
} \
} \
}
#endif // else not NDEBUG
对于上述测试用例,我可以通过添加另一个类似的未使用的函数来消除错误,如下所示:
template<typename T>
void
unused(T const) {
/* Do nothing. */
}
然而,当参数可以像这样被引用时,调用unused()的其他情况会因歧义而失败:
file.h:176: error: call of overloaded `unused(bool)' is ambiguous
myAssert.h:27: note: candidates are: void unused(T) [with T = bool]
myAssert.h:34: note: void unused(const T&) [with T = bool]
我的问题是,如何更改unused()或重载它以满足以下要求:
- 编译器可以将对unused()的调用优化为无操作。
- 它使得传递给unused()的表达式中出现的任何变量都被视为已使用,因此不会导致警告,即这些变量被定义但未使用。
- unused()的参数可能可以被引用,也可能不能被引用。
- unused()的参数可能是具有昂贵的复制构造函数的对象,在调用unused()时不应该调用该函数。
-William
!some_volatile_bool
的类型是bool
而不是volatile bool
- 因此,T
应该被推导为bool
而不是volatile bool
。请注意,非类类型的右值永远不会被声明为const/volatile。 - Johannes Schaub - litbunused(readWriteActivated)
,那听起来也像是他的意图。 - Potatoswatter