简体   繁体   中英

Type-casting using function call T(0) and templates

I have a function converting a "simulation domain" into an array of voxels (3D pixels). Each voxel can be 0 or 1, or at least false or true . As the domain can be really big, as the discretisation step can be very small, it requires a very big amount of memory.

I use my array of voxels to perform scattering simulations using FFTW3 (In that case, it's just great if the function can work on an array of double[2] (complex type known by FFTW3, so that I can perform in-place transform). But when I use my array of voxels to perform "simple" operations (volume fraction estimation for example) I just want my array to be of the smallest type I can work with, so an array of boolean would be just fine.

I was thinking of something like the following :

#include <iostream>
int N = 10 ;


template<typename T>
void voxelizator(T* & Voxels) {
    // N = total number of voxels, stored in a row-major 1D array
    if (Voxels==NULL) Voxels = new T[N] ; //
    for (int n = 0 ;  n < N ; n++) Voxels[n] = T(0) ;
    { // Code to voxelizate the space -- DUMB condition 
        for (int n = 0 ; n<N ; n++) if (n%2==0) Voxels[n] = T(1) ;
    }
}



int main()
{
    int * voxOfInt = NULL ;
    std::cout << "Array of int :" << std::endl ;
    voxelizator(voxOfInt) ;
    std::cout << "Done" << std::endl ;
    for (int n = 0 ; n < N ; n++)  std::cout << n << "\t" << voxOfInt[n] << std::endl ;
    delete[] voxOfInt ;

    bool * voxOfBool = NULL ;
    std::cout << "Array of boolean " << std::endl ;
    voxelizator(voxOfBool) ;
    std::cout << "Done" << std::endl ;
    for (int n = 0 ; n < N ; n++)  std::cout << n << "\t" << voxOfBool[n] << std::endl ;
    delete[] voxOfBool ;

}

but the error ISO C++ forbids casting to an array type 'double[2]' is fired when i call this function with an array of double[2] (complex from FFTW3) (or int[2] like in this example : )

...    
typedef double complex [2]  ;
...
// in main {}

    complex * voxOfArray = NULL ;
    std::cout << "Array of an array " << std::endl ;
    voxelizator(voxOfArray) ; // It fails to call the T(0) at compile time, but i would be more than happy to explain g++ what is T(0) for int[2] ...
    std::cout << "Done" << std::endl ;
    for (int n = 0 ; n < N ; n++)  std::cout << n << "\t" << voxOfArray[n] << std::endl ;
    delete[] voxOfArray ;

The question is : Where can I give g++ the recipie to typecast :

  • T(0) into {0,0} and T(1) into {1,0} when T is double[2] ?
  • T(0) into FALSE and T(1) into TRUE when T is a boolean ?

Note : The function call operator for a type seems weird to me but I know it works fine with the following sign function I already use (Please, insert here the picture of the dog doing some chemistry and saying "I've no idea what I'm doing")

template <typename T> int sign(T value) {
    return (T(0) < value) - (value < T(O)) ; 
}

If you are using C++11: You could use a helper struct like :

struct voxel_t {
    double val_[2];
    voxel_t() : val_{0.0, 0.0}{};
    explicit voxel_t(bool b): val_{double(b), 0.0}{};
};

template<typename T>
void voxelizator(T* Voxels) {
    // N = total number of voxels, stored in a row-major 1D array
    if (Voxels==NULL) Voxels = new T[N]{} ; // performs below initialization
    //for (int n = 0 ;  n < N ; n++) Voxels[n] = T(0) ;  // no longer needed
    { // Code to voxelizate the space 
        for (int n = 0 ; n<N ; n++) if (is_Matter(n)) Voxels[n] = T{true};
    }
}

Sample usage on ideone .

This solves the case of double[2] and for bool you don't need to do anything special.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM