Cleanup a bulky expression, document implementation details
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index f2e47ef..969d920 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -4741,6 +4741,35 @@
}
};
+ // If the matchee raises an exception of a wrong type, we'd like to
+ // catch it and print its message and type. To do that, we add an additional
+ // catch clause:
+ //
+ // try { ... }
+ // catch (const Err&) { /* an expected exception */ }
+ // catch (const std::exception&) { /* exception of a wrong type */ }
+ //
+ // However, if the `Err` itself is `std::exception`, we'd end up with two
+ // identical `catch` clauses:
+ //
+ // try { ... }
+ // catch (const std::exception&) { /* an expected exception */ }
+ // catch (const std::exception&) { /* exception of a wrong type */ }
+ //
+ // This can cause a warning or an error in some compilers. To resolve
+ // the issue, we use a fake error type whenever `Err` is `std::exception`:
+ //
+ // try { ... }
+ // catch (const std::exception&) { /* an expected exception */ }
+ // catch (const NeverThrown&) { /* exception of a wrong type */ }
+ using DefaultExceptionType = typename std::conditional<
+ std::is_same<
+ typename std::remove_cv<
+ typename std::remove_reference<Err>::type>::type,
+ std::exception>::value,
+ const NeverThrown&,
+ const std::exception&>::type;
+
public:
ExceptionMatcherImpl(Matcher<const Err&> matcher)
: matcher_(std::move(matcher)) {}
@@ -4771,14 +4800,7 @@
} else {
return true;
}
- } catch (
- typename std::conditional<
- std::is_same<
- typename std::remove_cv<
- typename std::remove_reference<Err>::type>::type,
- std::exception>::value,
- const NeverThrown&,
- const std::exception&>::type const& err) {
+ } catch (DefaultExceptionType err) {
#if GTEST_HAS_RTTI
*listener << "throws an exception of type "
<< GetTypeName(typeid(err)) << " ";