C++语言模板题

标签 c++ templates

下面是一个小测试用例,演示了我试图在 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 抑制优化代码中出现的未使用变量警告。我有一个执行断言检查的宏,在优化代码中断言消失了,但我希望断言表达式中的任何变量都保持引用状态,这样我就不会只在优化代码中收到未使用的变量警告。在 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() 或重载它,使其满足以下要求:

  1. 编译器可以将对 unused() 的调用优化为空操作。
  2. 它会导致传递给 unused() 的表达式中存在的任何变量显示为已使用,因此不会导致有关它们已定义但未使用的警告。
  3. unused() 的参数可能会或可能不会被引用。
  4. unused() 的参数可能是一个具有昂贵复制构造函数的对象,在调用 unused() 时不应调用它。

谢谢。

-威廉

最佳答案

实现此目的的一种常见(且简单得多)方法是将结果强制转换为 void

(void) x;

其中 x 是一些其他未引用的值。

关于C++语言模板题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2025153/

相关文章:

来自键盘输入的 C++ 通用数据

c++ - 初始化字符串指针数组并通过函数调用打印相同的内容不起作用,为什么?

c++ - 使用 OpenCV 进行对象检测和隔离

c++ - 使用 '<' 运算符而不是 '==' 运算符的 std::set<Key,Compare,Allocator>::find() 函数背后的直觉是什么?

asp.net-mvc-3 - MVC2 - 如何在模板中获取父模型(容器)

c++ - 给定一个整数 M,使 (int)C < M 的最大 float C 是多少?

c++ - 不应该 decltype 触发其参数的编译吗?

c++ - 这里是否需要类型名称?

C++实现模板类时编译错误

html - 客户端上的 Dart HTML 模板 : Separating HTML from Dart code