Может ли аргумент шаблона быть выражением? - PullRequest
3 голосов
/ 23 октября 2011

Я хочу сделать это:

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.

Возможно ли получить выражение какпараметр шаблона?

Ответы [ 3 ]

6 голосов
/ 23 октября 2011

Шаблоны обрабатываются во время компиляции, и это означает, что вы можете использовать только константные выражения , ни один из которых не может выдать, поэтому простой ответ заключается в том, что вы не можете делать то, что вы хотите там.

Хотя в большинстве случаев я против макросов, это одно из тех немногих мест, где они имеют смысл, и если вы посмотрите на тестовые среды, то обнаружите, что макросы являются общим решением для этой конкретной проблемы.

3 голосов
/ 23 октября 2011

В этом случае функция, принимающая другую функцию для имитации передачи по имени, может работать, если вы не возражаете

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;
}
0 голосов
/ 23 октября 2011

Параметр шаблона может быть константным выражением, как указал Дэвид. Это то, что вы были после?

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;
}
...