The Quantum Physicist - 1 year ago 56

C++ Question

I have a function that generates random number for my array. I created two overloads for floating-point numbers and integers as follows:

`template <typename T, int M = 0>`

typename std::enable_if<std::is_floating_point<T>::value && std::is_scalar<T>::value,MyArray<T,M> >::type

Random()

{

//...

}

template <typename T, int M = 0>

typename std::enable_if<std::is_integral<T>::value && std::is_scalar<T>::value, MyArray<T,M> >::type

Random()

{

//...

}

These functions can be called with:

`MyArray<int> i = Random<int>();`

MyArray<double> d = Random<double>();

I would like to achieve the same but with

`std::complex<T>`

`T`

`//This is what I'm trying to achieve`

MyArray<std::complex<double> > = Random<std::complex<double>>();

MyArray<std::complex<float > > = Random<std::complex<float >>();

I was unable to achieve this exactly, but was able to achieve:

`Random<std::complex,double>()`

using template template parameters, which is not what I'm looking for.

How can I get the overload with

`<std::complex<double>>`

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

I suppose that creating an extractor helper (to, by example, extract `float`

from `std::complex<float>`

) as

```
template <typename T>
struct extractType;
template <template <typename ...> class C, typename D>
struct extractType<C<D>>
{ using subType = D; };
```

you can use it and write

```
template <typename T, int M = 0,
typename D = typename extractType<T>::subType>
typename std::enable_if< std::is_same<T, std::complex<D>>::value
&& std::is_floating_point<D>::value
&& std::is_scalar<D>::value, MyArray<T,M> >::type
Random ()
{ return MyArray<T,M>{}; }
```

or simply

```
template <typename T, int M = 0,
typename D = typename extractType<T>::subType>
typename std::enable_if<std::is_same<T, std::complex<D>>::value,
MyArray<T,M> >::type
Random ()
{ return MyArray<T,M>{}; }
```

if you can consider obvious that the template argument of `std::complex`

is floating and scalar.

**--- EDIT ---**

Added a full example (well... with a false `MyArray`

)

```
#include <array>
#include <complex>
#include <type_traits>
template <typename T, int M = 0>
using MyArray = std::array<T, 10U>;
template <typename T>
struct extractType;
template <template <typename ...> class C, typename D>
struct extractType<C<D>>
{ using subType = D; };
template <typename T, int M = 0>
typename std::enable_if<std::is_floating_point<T>::value && std::is_scalar<T>::value,MyArray<T,M> >::type
Random ()
{ return MyArray<T,M>{}; }
template <typename T, int M = 0>
typename std::enable_if<std::is_integral<T>::value && std::is_scalar<T>::value, MyArray<T,M> >::type
Random ()
{ return MyArray<T,M>{}; }
template <typename T, int M = 0,
typename D = typename extractType<T>::subType>
typename std::enable_if<std::is_same<T, std::complex<D>>::value,
MyArray<T,M> >::type
Random ()
{ return MyArray<T,M>{}; }
int main()
{
MyArray<int> i = Random<int>();
MyArray<double> d = Random<double>();
MyArray<std::complex<float>> c = Random<std::complex<float>>();
}
```

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**