Reputation: 126
I want to create an alias of std::array
with only numeric types
template<typename T, std::size_t n, T = std::is_arithmetic<T>::value>
using NumericArray = std::array<T, n>;
this works correctly with an integer
NumericArray<int, 2> i{1, 2};
But if I want a float or double I have an error due to the non-type template parameter
NumericArray<float, 2> f{1.0f, 2.0f};
There is some other way to do this?
Upvotes: 9
Views: 445
Reputation: 75755
(Hopefully) very soon we will be able to write it very cleanly using concepts:
template <class T>
concept constexpr bool Arithmetic = std::is_arithmetic_v<T>;
template <Arithmetic T, std::size_t n>
using NumericArray = std::array<T, n>;
And btw, this compiles and runs now on gcc 7 with -fconcepts
. For gcc 6 you need to use std::is_arithmetic<T>::value
In c++14 you have some ways too.
I prefer:
template <class T, std::size_t n,
class Enable = std::enable_if_t<std::is_arithmetic<T>::value>>
using NumericArray = std::array<T, n>;
@holyblackcat gave you another way in his answer
Upvotes: 7
Reputation: 96334
If you want to prevent someone form using this alias with non-arithmetic types, then you did it wrong.
Your code will allow any type that is a valid template argument and can be constructed from bool
and that's all.
The proper solution would be something like this:
template <typename T, std::size_t n>
using NumericArray = std::enable_if_t<std::is_arithmetic<T>::value, std::array<T, n>>;
Why your code doesn't work:
Look at this part:
template<typename T, std::size_t n, T = std::is_arithmetic<T>::value>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It creates an unnamed template argument of type T and sets a default value for it.
Even if std::is_arithmetic<T>::value
is false, the code will compile as long as T
can be constructed from bool
.
Of course, T
must be also usable as a template argument. (That's why float
does not work. Floating-point types can't be template arguments. See this: Why can't I use float value as a template parameter?)
Again, there is just no reason for the compiler to generate any errors if std::is_arithmetic<T>::value
is false.
For example, your code will allow following type:
struct S
{
constexpr S(bool) {}
};
Upvotes: 10