Rafael Adel
Rafael Adel

Reputation: 7759

C++ - creating an alias for an std::array of std::array iterator

I have an array of iterators of type std::array<Point, SIZE>::iterator, where SIZE is a template variable.

So having an array of these iterators would be

std::array<std::array<Point, SIZE>::iterator, SIZE> 

which is a pain to write in the number of functions that I have.

I was thinking of aliasing this type, but I don't know how, while having template variable SIZE.

I tried

template<std::size_t SIZE>
using p_iterators = std::array<std::array<Point, SIZE>::iterator, SIZE>;

And inside the function I did :

template<std::size_t SIZE>
template <typename T>
p_iterators<SIZE> eucledian_closest(T &points) {}

I got these errors:

closest_pair.cpp:24:70: error: type/value mismatch at argument 1 in template parameter list for ‘template<class _Tp, long unsigned int _Nm> struct std::array’
 using p_iterator = std::array<std::array<Point, SIZE>::iterator, SIZE>;
                                                                      ^
closest_pair.cpp:24:70: error:   expected a type, got ‘std::array<Point, SIZE>::iterator’
closest_pair.cpp:42:1: error: ‘p_iterator’ does not name a type
 p_iterator<SIZE> eucledian_closest(T &points) {

I don't know how to alias such a type or even how to use it with that template while having another template in the function template <typename T>.

Upvotes: 0

Views: 407

Answers (3)

WhiZTiM
WhiZTiM

Reputation: 21576

In C++, dependent template type names require the keyword, typename.

You should change your alias from

template<std::size_t SIZE>
using p_iterators = std::array<std::array<Point, SIZE>::iterator, SIZE>;

to

template<std::size_t SIZE>
using p_iterators = std::array<typename std::array<Point, SIZE>::iterator, SIZE>;

Then change the template function signature to this:

template<std::size_t SIZE, typename T>
p_iterators<SIZE> eucledian_closest(T &points) {}

In the above case, when calling the function, eucledian_closest, you will at least need to explicitly provide the SIZE parameter like eucledian_closest<3>(myArry). Without doing so, type deduction will fail to deduce SIZE, plus the down side is that you should have the size to match. If you want type deduction to deduce it implicitly SIZE for you:

You can do something like:

template<template <typename, std::size_t> class Array,
                                          typename T,
                                          std::size_t SIZE
        >
p_iterators<SIZE> eucledian_closest(Array<T, SIZE>& points) {}

With the above, you can do eucledian_closest(myArray). However, if you do not need to use SIZE in the function, you could simply do

template<typename T>
auto eucledian_closest(T& points) {}

And simply call it like eucledian_closest(myArray).

Upvotes: 2

pzelasko
pzelasko

Reputation: 2322

Other answers explain how to correct your alias. As to the function, I think there are several ways to fix this. The easiest one is to use type deduction for the returned value, which you can apply if you expect T to be of the std::array type:

template <typename T>
auto euclidean_closest(T& points) { 
  // some code
  T some_arr;  // the compiler will know what size to use
  return some_arr;
}

If you need to provide the SIZE, you can use:

template <typename T, size_t SIZE>
p_iterators<SIZE> euclidean_closest(T& points) {}

Upvotes: 0

krzaq
krzaq

Reputation: 16431

you need to add typename for your dependant type

template<std::size_t SIZE>
std::array<typename std::array<Point, SIZE>::iterator, SIZE>

By the way, the following function template doesn't make any sense:

template<std::size_t SIZE>
template <typename T>
p_iterators<SIZE> eucledian_closest(T &points) {}

You may only have one template parameter list for a free function template, you probably want

template<std::size_t SIZE, typename T>
p_iterators<SIZE> eucledian_closest(T &points) {}

Upvotes: 0

Related Questions