void Assert(bool b, const string& hint) {
AssertEqual(b, true, hint);
}
void AssertEqual (class T& t, const U& u, const string& hint) { if (t != u) {
ostringstream os;
os << "Assertion failed: " << t << "!=" << u << "Hint: " << hint; throw runtime_error(os);
} }
T
, u
, в самом AssertEqual
- ничего не отражающих именах. В изломанной структуре кода, в кривом выравнивании блоков. Только hint
отражает свою суть, однако ничего не означает в контексте конструкции утверждений.true
вставлена как магическое значение. В другом месте новый параметр будет вычислен. Где-то еще значение будет прочитано из сетевого сокета или файла. AssertEqueal
является неполным. Это шаблон функции, но описания шаблонных параметров нет.ax^2 + bx + c = 0
. Решаем, пишем: x = 42
. И так далее.Assert
- переводится как "Утверждать". Утверждать что-то. Значит, где-то должно быть утверждение. Но у AssertEqueal
этого утверждения нет. Более того, имя функции переводится как "Утверждать равным". Чему равным?TerminateOnDifferent
- выпилиться по разнице значений.Condition
, условие. Правый - это Reference
, норма/эталон.Terminate
однозначно читается в контексте процесса. Прозрачно и то, что по наступлении эквивалентности выхода из этой функции не будет. Следовательно, все, что можно еще сделать, это передать семантику терминации в виде причины. Третий параметр - это Reason
. Вот так, без всяких лишних hint
и Msg
, т.к. аргумент самодокументируется своим типом.template< typename TCondition, typename TReference >
void TerminateOnDifferent( TCondition&& condition, TReference&& reference, const std::string_view reason )
{
if( condition == reference )
{
return;
}
std::cout << "Termination happened due to reason: " << reason << "." << std::endl;
std::terminate();
}
В целом, продемонстрированный тобой код является высоким образчиком невежества и крайней небрежности в исполнении кода. В буквальном смысле, без запуска и трассировки по этому коду ничего сказать нельзя. Такой код принято полностью стирать и восстанавливать его логику максимально понятным способом.