Да, на самом деле есть. Вам нужно будет написать собственную функцию assert самостоятельно, так как assert()
в C ++ - это в точности C assert()
с включенной в нее * функцией '1003 *. К счастью, это удивительно просто.
Assert.hh
template <typename X, typename A>
inline void Assert(A assertion)
{
if( !assertion ) throw X();
}
Приведенная выше функция выдаст исключение, если предикат не выполняется. Тогда у вас будет шанс поймать исключение. Если вы не поймаете исключение, будет вызван terminate()
, который завершит программу аналогично abort()
.
Вы можете спросить, как насчет оптимизации утверждения, когда мы создаем для производства. В этом случае вы можете определить константы, которые будут означать, что вы создаете для производства, а затем обратиться к константе, когда вы Assert()
.
debug.hh
#ifdef NDEBUG
const bool CHECK_WRONG = false;
#else
const bool CHECK_WRONG = true;
#endif
main.cc
#include<iostream>
struct Wrong { };
int main()
{
try {
Assert<Wrong>(!CHECK_WRONG || 2 + 2 == 5);
std::cout << "I can go to sleep now.\n";
}
catch( Wrong e ) {
std::cerr << "Someone is wrong on the internet!\n";
}
return 0;
}
Если CHECK_WRONG
является константой, то вызов Assert()
будет скомпилирован в производственном процессе, даже если утверждение не является константным выражением. Есть небольшой недостаток в том, что, ссылаясь на CHECK_WRONG
, мы печатаем немного больше. Но взамен мы получаем преимущество в том, что мы можем классифицировать различные группы утверждений и включать и отключать каждое из них по своему усмотрению. Так, например, мы можем определить группу утверждений, которые мы хотим включить даже в рабочем коде, а затем определить группу утверждений, которые мы хотим видеть только в сборках разработки.
Функция Assert()
эквивалентна вводу
if( !assertion ) throw X();
но это ясно указывает на намерение программиста: сделать утверждение. Утверждения также легче найти с помощью этого подхода, как простые assert()
s.
Подробнее об этой технике см. Бьярн Страуструп «Язык программирования C ++ 3e», раздел 24.3.7.2.