模板参数可以是表达式吗?

Can a template argument be an expression?

本文关键字:表达式 参数      更新时间:2023-10-16

我想这样做:

template<T>
bool AssertThrows() {
  try {
    T; // T is an expression, so evaluate it here
    return false;
  } catch(...) {
    return true;
  }
}
int main() {
  bool throws = !AssertThrows<5 + 2>();
  return !throws;
}

但这不起作用:我得到的是这些编译器错误:

$ clang++ a.cc
a.cc:1:10: error: unknown type name 'T'
template<T>
         ^
a.cc:4:5: error: use of undeclared identifier 'T'
    T; // T is an expression
    ^
2 errors generated.

是否可以将表达式作为模板参数?

模板是在编译时处理的,这意味着你只能使用常量表达式,它们都不会抛出,所以简单的答案是你不能在那里做你想做的。

虽然我反对在大多数情况下使用宏,但这是它们有意义的少数几个地方之一,如果您查看测试框架,您会发现宏是这个特定问题的通用解决方案。

在这种情况下,如果您不介意,可以使用另一个函数来模拟按名称传递的函数

template<typename T>
bool AssertThrows(T t) {
  try {
    t(); // t contains an expression, so evaluate it here
    return false;
  } catch(...) {
    return true;
  }
}
int main() {
  bool throws = !AssertThrows([]{ 5 + 2; });
  return !throws;
}

模板参数可以是常量表达式,正如David指出的那样。这就是你要找的吗?

template<int Expr>
bool AssertThrows() {
  try {
    Expr; // Expr is a constant expression that 'is' an int, so evaluate it here
    return false;
  } catch(...) {
    return true;
  }
}
int main() {
  bool throws = !AssertThrows<5 + 2>();
  return !throws;
}