Only mark functions as noexcept when you can guarantee they won’t throw exceptions under any circumstances. Common pitfalls include:
std::make_tuple, or working with collections might allocate memory and throw.noexcept.For complex templated code, consider compile-time validation:
// Before marking a templated function as noexcept
template <typename DataDrivenPaintProperty, typename Evaluated>
static bool isConstant(const Evaluated& evaluated) noexcept {
// How do you know all operations here are truly noexcept?
return evaluated.template get<DataDrivenPaintProperty>().isConstant();
}
// Better: Add compile-time verification
template <typename DataDrivenPaintProperty, typename Evaluated>
static bool isConstant(const Evaluated& evaluated) noexcept {
using ReturnType = decltype(evaluated.template get<DataDrivenPaintProperty>());
static_assert(std::is_nothrow_invocable_v<decltype(&ReturnType::isConstant), ReturnType&>,
"isConstant() must be noexcept");
return evaluated.template get<DataDrivenPaintProperty>().isConstant();
}
When in doubt, err on the side of caution and omit noexcept. Incorrect noexcept specifications can lead to program termination if an exception is thrown, which is worse than having a potentially throwing function not marked as noexcept.
Enter the URL of a public GitHub repository