The idea is that I have a function that does something arithmetic to the input, so maybe something like:
#include <type_traits>
#include <vector>
using namespace std;
template<typename T>
double mean(const vector<T>& vec)
{
static_assert(is_arithmetic<T>::value, "Arithmetic not possible on this type");
//compute mean (average)
}//mean
This works great, and computes the mean for all the number types that I put in. But lets say I then create a new class:
class foo
{
// class that has arithmetic operations created
};// foo
And in the definition of this class, I defined the needed operators, + and /, so they work with expected inputs. Now I want to use my mean function with my new class, but it obviously won't compile due to the static_assert. So how do I tell the compiler that my new class should satisfy is_arithmetic<foo>::value
?
It would be great if when I create the class I could give it a type that satisfies is_arithmetic, but this seems like it might cause a problem with type_traits somehow?
Or would I need to create a new test, that checks to see
is_arithmetic<T>::value || type(T,foo)
or something like that?
I'd prefer to only have to adapt my class, rather than the function if possible, but I'm curious for a solution.
The standard library type traits, such as
std::is_arithmetic
, with one exception (std::common_type
), are "set in stone". Attempting to specialize them causes undefined behavior.is_arithmetic
tests if the type is an arithmetic type as defined by the standard; user-defined types are never arithmetic types.You can write your own trait that tests for support for the arithmetic operators:
The partial specialization will match only if all four expressions are well-formed (i.e., that
T
supports operators+, -, *, /
).Demo.
std::is_arithmetic<T>::value
is by definition onlytrue
ifT
is arithmetic type in terms of C++ standard, which is integral or floating type, which in turn are fundamental types only: