Ben
Ben

Reputation: 2725

c++ template method syntax issue

I am trying to create a method that creates an array of double the size given, then fills the first half of the array with the original values and the second half with the original values in reverse order. I have completed this but the next task is to make the method accept arrays of generic type and i'm stuck and not sure where to go from here my code so far:

template <typename T>

T& *copy_and_reverse(T& *a, int length) {
    T& *result = new T&[length*2];
    int w = length-1;
    for (int i = 0; i < length * 2; i++) {
        if (i < length) {
            result[i] = a[i];
        } else {
            result[i]=a[w];
            w--;
        }
    }
    return result;
}

int main() {
    double numbers[5]={8.364,4.3,5.3,9.6,7.645};
    int size=sizeof numbers/sizeof(double);
    double *pointertonumbers;
    pointertonumbers=copy_and_reverse(numbers, size);
    for(int i=0;i<size*2;i++){
        cout<<pointertonumbers[i]<<"\n";
    }
}

at the moment the code does not work as i get multiple "error: cannot declare pointer to 'T&'"

Upvotes: 1

Views: 85

Answers (2)

Lol4t0
Lol4t0

Reputation: 12557

First, you cannot create pointer to reference (what you are trying to do). Reference to a pointer would be T* &a. And you should not return pointer to a reference (and reference to a pointer either, as it will create dangling reference)

Actually, it's better to be on a safe side and accept a reference to an array.

T* copy_and_reverse(T (&a) [N]) {
    T *result = new T[N*2];
    size_t w = N-1;
    for (size_t i = 0; i < N * 2; i++) {
        if (i < N) {
            result[i] = a[i];
        } else {
            result[i]=a[w];
            w--;
        }
    }
    return result;
}

int main() {
    double numbers[5]={8.364,4.3,5.3,9.6,7.645};
    int size=sizeof numbers/sizeof(double);
    double *pointertonumbers;
    pointertonumbers=copy_and_reverse(numbers);
    for(int i=0;i<size*2;i++){
        std::cout<<pointertonumbers[i]<<"\n";
    }
    delete [] pointertonumbers;
}

This still have issues. You should not forget to delete result of a function. With C++11 you can rewrite it really safe with std::arrays:

std::array<T, N*2> copy_and_reverse(const std::array<T, N>& orig) {
    std::array<T, N*2> result;
    std::copy(orig.begin(), orig.end(), result.begin());
    std::copy(orig.begin(), orig.end(), std::reverse_iterator<typename std::array<T, N*2>::iterator>(result.end()));
    return std::move(result);
}

int main() {
    std::array<double, 5> numbers = {{8.364,4.3,5.3,9.6,7.645}};

    auto pointertonumbers(copy_and_reverse(numbers));
    for(size_t i=0;i<pointertonumbers.size();i++){
        std::cout<<pointertonumbers[i]<<"\n";
    }
}

Here you get rid of pointers (and all its issues) completely.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

If the compilre says that it cannot declare pointer to T& then try to declare a reference to T *. Maybe the compiler will be happy in this case.:)

T * copy_and_reverse( const T *a, int length) {
    T *result = new T[length*2];

As for me I would use standard algorithm std::copy. For example

template <typename T>
T * copy_and_reverse( const T *a, size_t length) 
{
    T *result = new T[ 2 * length ];

    std::copy( a, a + length, result );

    std::copy( a, a + length, reverse_iterator<int *>( result + 2 * length ) );

    return result;
}

Upvotes: 1

Related Questions