简体   繁体   中英

Template arguments are invalid (unique pointer)

I am trying to make an N-dimensional array class that is dynamically resizable. My templated class has the signature ndarray<typename data_type, int dimensions> . To hold the array I want to use a unique pointer class member to hold a templated vector of the types std::vector<type_t> for 1D, std::vector<std::vector<type_t>> for 2D, std::vector<std::vector<std::vector<type_t>>> for 3d ect...

The unique pointer will have a different signature depending on the number of dimensions. I wanted to have the class constructor for ndarray to set the signature of the unique pointer and use new to make the new vector but I would need an auto member variable to be set to a vector of the type of the member variable which doesn't work. My current aproach is to use a templated function that returns an object of the type the array needs to be, template<typename data_type> auto dimension_helper(int dimensions) and then set the unique pointer signature like this std::unique_ptr<decltype(<data_type>dimension_helper(dimens))> array . This also does not work, giving me the errors template argument 1 is invalid and template argument 2 is invalid inside the unique pointer.

What can I do to make my existing code work, or is there a better way at approaching the problem in a similar way?

Code samples

header

#ifndef ND_H_
#define ND_H_
#include <cstring>
#include <vector>
#include <memory>


namespace NdArray{
    //use the following for dimension types 
    template<typename T>
    using d1 = std::vector<T>;
    template<typename T>
    using d2 = std::vector<d1<T>>;
    template<typename T>
    using d3 = std::vector<d2<T>>;
    template<typename T>
    using d4 = std::vector<d3<T>>;
    template<typename T>
    using d5 = std::vector<d4<T>>;

    template<typename data_type>
    auto dimension_helper(int dim);



    template<typename data_type,int dimensions>
    class ndarray{
            int dims;
            std::unique_ptr<std::vector<int>> xsub_spans;

        public:
            ndarray();
            ~ndarray();
            std::unique_ptr<decltype(<data_type>dimension_helper(dimensions))> array;

            template<typename dat_type, int dim>
            friend std::ostream& operator<<(std::ostream& , ndarray<dat_type, dim>&);
    };

}


#endif

definitions so far

#include "nd.h" 
using namespace NdArray;

template<typename data_type, int dimensions>
ndarray<data_type, dimensions>::ndarray(){
    dims = dimensions;
    array = new <data_type>dimension_helper(dimensions); 
}

template<typename data_type>
auto dimension_helper(){
    switch (dims) {
        case 1 : {
            d1<data_type> type;
            return type;
            break;
        }
        case 2 : {
            d2<data_type> type;
            return type;
            break;
        }
        case 3 : {
            d3<data_type> type;
            return type;
            break;
        }
        case 4 : {
            d4<data_type> type;
            return type;
            break;
        }
        case 5 : {
            d5<data_type> type;
            return type;
            break;
        }
    }
}

A template argument list comes after the template's name, so:

dimension_helper<data_type>(dimensions)

instead of

<data_type>dimension_helper(dimensions)

However, your "dimension helper" has no chance to work, as the switch statement is a runtime branch, and fails to compile because the types of expressions in return statements are unequal. Instead, you can rewrite it as follows:

template <typename T>
struct identity { using type = T; };    
template <typename T, std::size_t D>
struct dimension_helper : identity<std::vector<typename dimension_helper<T, D-1>::type>> {};
template <typename T>
struct dimension_helper<T, 0> : identity<T> {};
template <typename T, std::size_t D>
using dimension_helper_t = typename dimension_helper<T, D>::type;

and declare your pointer as:

std::unique_ptr<dimension_helper_t<data_type, dimensions>> array;

DEMO

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