When you use templates in C++, the user can normally plug any C type in a program. For a template class I developed (read C++ callbacks and templates ), I want to restrict one of the template arguments: R. This is the type of the return value of a callback function. The restriction that I want to impose, is that the function should not return an object, array, string, ... . Numeric and bool types should do. Or return nothing (void).
I want to be able to return a 0 if no function is set in _callback. So as long as the return value is a C++ arithmetic types, I'll be good. My mechanism will fail if a developer wants to use functions that return strings, arrays, objects, ...
I think that being able to return any arithmetic type is flexible enough for a generic callback handler.
template <typename R, typename... Args>
// restrict to arithmetic data types for return value, or void
requires std::is_void<R>::value || std::is_arithmetic_v<R>
class Callback {
// ...
/*
* R can either be an arithmetic type, or void
*/
inline R call(Args... args) {
if constexpr (std::is_void<R>::value) {
if (_callback == nullptr) {
return;
}
(*_callback)(args...);
}
if constexpr (! std::is_void<R>::value) {
if (_callback == nullptr) {
return 0; // R can only be a arithmetic type. 0 should work as default.
}
return (*_callback)(args...);
}
}
// ...
I could do nothing. In that case the developer would get a compilation error on this line in my code: return 0;. And they 'll have to go and investigate why my code throws an error.
C++ now has a mechanism that's called concept. With that, I can restrict the C++ type that a particular template attribute can have. I will use that to only allow arithmetic types for the return value type R.
When doing that, the compiler will give a clear message, pointing to the user's code line where they defined an invalid return type:
78 | Callback<std::string, const int&, const int&> cb;
error: template constraint failure for 'template<class R, class ... Args> requires std::is_arithmetic<_Tp>::value class Callback'note: constraints not satisfied
Thank you for reading. Check C++ and templates: callbacks that return a value, or a void for yet another dive into hip C++...

