将不同大小的C阵列传递给模板化函数,取2个相同的参数

时间:2016-05-22 03:21:23

标签: c++ arrays templates stl

我有一个模板化函数func如下所示,它接受两个相同类型的参数(通常是两个相同类型但不同大小的STL容器)。我想让它与相同类型但不同大小的的C数组一起工作。

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 << " ";
    }
}

显然,以下代码失败了error: no matching function for call to 'func(int [2], int [3])'

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

我无法改变功能签名,但我可以重载它。我也想避免不必要的副本。我的尝试是写一个像:

这样的重载
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
}

但是,我不确定如何实现它。欢迎任何想法。谢谢!

根据demo直播this answer

3 个答案:

答案 0 :(得分:2)

您需要创建一个range<T*>结构来包装数组,并为其定义begin()end()函数。

可以像

一样简单
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) );

然后,您可以使用此构建块轻松编写func(T[N], T[M])重载。

如果您不喜欢工厂函数方法,也可以编写模板化(on N)构造函数。

它可以用来代替任何标准容器,因为它支持begin / end操作。它可以引用整个数组,数组的连续子集,或任何标准容器的连续子序列。

答案 1 :(得分:0)

  

以某种方式调用f(const T&amp;,const T&amp;)而不复制数组   元素

当然,由于该模板函数返回两个相同类型的参数,因此无法工作。

需要做的是简单地将数组作为指针传递,并给出每个相应数组的大小。毕竟,学习数组的第一件事是数组可以转换为指向数组第一个元素的指针。这样:

template<class T>
void func(const T *a, const T *b, size_t a_size, size_t b_size) {

   // ...
}

现在,你的

template<class T, size_t M, size_t N>
void func(const T (&a)[M], const T (&b)[N])

应该可以简单地做这样的事情:

func(&a[0], &b[0], M, N);

你&#34;真实&#34;然后func()将知道每个数组的大小。

答案 2 :(得分:0)

一种选择是使用转发参考:

template<class T, class U>
void func(T&& a, U&& b)
{
    for(auto x : a)
        cout << x << " ";
    cout << endl;

    for(auto x : b)
        cout << x << " ";
}

然后你可以传递你的其他容器或你的C风格的数组。参数通过引用传递,因此数组长度信息可用。

NB。考虑在循环中使用auto&&auto const &,以避免在容器中复制元素。