C语言模板问题

下面是一个小测试用例,它演示了我尝试使用C中的模板解决的问题:
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()模板函数的定义中,我使用引用,以便不会无意中运行复制构造函数代码,以便编译器可以完全忽略对未使用的调用.

对于那些感兴趣的人,断言宏看起来像这样:

#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()时不应调用该对象.

谢谢.

-威廉

解决方法

正如约翰内斯在评论中所说,你遇到了编译错误.您可以通过显式转换为bool来解决它:
unused( bool( !readWriteActivated) ); // add bool() to any (!volatile_bool_var)

旧答案(但仍然不是一个坏主意)

如果我回想起const-volatile资格规则,你只需要更多地验证虚拟变量.基本上,您只想在声明的类型中将错误消息反馈:vP.

template<typename T>
void
unused(T const volatile &) { // only change is to add "volatile"
  /* Do nothing. */
}

另外,很好的是你把const放在它所属的类型之后.

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...