Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing C-arrays of different sizes to templated function taking 2 identical parameters

I have a templated function func as follows which takes two parameters of the same type (usually two STL containers of the same type but different sizes). I want to make it work with C-arrays of the same type but different sizes too.

template<class T>
void func(const T& a, const T& b) {
    // some code like as follows
    for(auto x : a) {
        cout << x << " ";
    }
    cout << endl;
    for(auto x : b) {
        cout << x << " ";
    }
}

Obviously, the following code fails with error: no matching function for call to 'func(int [2], int [3])':

int a1[] = {1, 2};
int a2[] = {3, 4, 5};
func(a1, a2);

I cannot alter the function signature but I can overload it. I also want to avoid unnecessary copies too. My attempt was to write an overload like:

template<class T, size_t M, size_t N>
void func(const T (&a)[M], const T (&b)[N]) {
    //somehow calling f<T>(const T&, const T&) without copying array elements
}

But, I am not sure how to implement it. Any ideas are welcome. Thanks!

Live demo based on this answer.

like image 358
Eissa N. Avatar asked Dec 19 '25 05:12

Eissa N.


1 Answers

You need to make a range<T*> structure to wrap your array, and define begin() and end() functions for it.

It can be as simple as

template<typename Iterator>
struct range { Iterator begin_, end_; };

template<typename T>
T begin(const range<T>& ar) { return ar.begin_; }

template<typename T>
T end(const range<T>& ar) { return ar.end_; }

template<typename T, size_t N>
range<T*> make_array_range(T (&array)[N])
{
     using std::begin; using std::end;
     return { begin(array), end(array) };
}

func( make_array_range(a1), make_array_range(a2) );

You can then easily write your func(T[N], T[M]) overload using this building block.

You could also write a templated (on N) constructor if you don't like the factory function approach.

It can be used in place of any standard container because it supports the begin/end operations. And it can refer to a whole array, contiguous subset of an array, or to a contiguous subsequence of any standard container.

like image 125
Ben Voigt Avatar answered Dec 20 '25 20:12

Ben Voigt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!