Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create alias for numeric array

Tags:

c++

c++11

c++14

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?

like image 584
michal915 Avatar asked Sep 16 '16 07:09

michal915


People also ask

How do I use the alias name generator?

Use our alias name generator to create a clever alias for yourself. The alias creator will present a new random alias each time you click the button. An alias is useful for online games and internet sites which require you to register. The alias maker includes both a first name alias and last name alias.

What is an alias maker?

An alias is useful for online games and internet sites which require you to register. The alias maker includes both a first name alias and last name alias. You can choose to create either male or female alias names.

What is an alias in SQL?

SQL aliases are used to give a table, or a column in a table, a temporary name. Aliases are often used to make column names more readable. An alias only exists for the duration of that query. An alias is created with the AS keyword. In this tutorial we will use the well-known Northwind sample database.

How do I create a ndarray in NumPy?

Create a NumPy ndarray Object NumPy is used to work with arrays. The array object in NumPy is called ndarray. We can create a NumPy ndarray object by using the array () function.


2 Answers

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) {}
};
like image 99
HolyBlackCat Avatar answered Sep 22 '22 12:09

HolyBlackCat


(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

like image 34
bolov Avatar answered Sep 20 '22 12:09

bolov