模板函数在C ++中查找子数组

时间:2015-12-27 20:07:20

标签: c++ templates

#include <iostream>
#include <string>

using namespace std;

template <class T> int IsSubArr(T& a, int a_len, T& b, int b_len)
{
    int i,j;
    bool found;
    int k;
    T& s=a,l=b;

    int s_len = (a_len < b_len) ? a_len : b_len; // find the small array length
    if (s_len == a_len) // check to set pointers to small and long array
    {
        s = a;
        l = b;
    }
    else
    {
        s = b;
        l = a;
    }


    for (i = 0; i <= a_len-s_len; i++) //loop on long array
    {
        found = true;
        k=i;
        for (j=0; j<s_len; j++) // loop on sub array
        {
            if (s[j] != l[i])
            {
                found = false;
                break;
            }
            k++;
        }
    }

    if (found)
      return i;
    else
      return -1;
}


/******* main program to test templates ****/
int main()
{

    int array[5] = {9,4,6,2,1};
    int alen = 5;
    int sub_arr[3] = {6,2,1};
    int slen = 3;

    int index= 0;
    index = IsSubArr(array,alen,sub_arr,slen);
    cout << "\n\n Place of sub array in long array: " << index;

    cout << endl;

    return 0;

}

这段代码:

index = IsSubArr(array,alen,sub_arr,slen);

我收到错误:

Error   1   error C2782: 'int IsSubArr(T &,int,T &,int)' : template parameter 'T' is ambiguous  

请帮忙解决此问题?

3 个答案:

答案 0 :(得分:1)

由于array[a]array[b] a != b有2种不同的类型,因此您需要2个类型模板args。
解决方法是使用指针。

+ template <class T> int IsSubArr(T* a, int a_len, T* b, int b_len)
+ T* s = a; T*l = b;

答案 1 :(得分:1)

您将第一个和第三个参数定义为参考

template <class T> int IsSubArr(T& a, int a_len, T& b, int b_len)
                                ^^^^             ^^^^

并传递这些参数的参数两个具有不同类型的数组

int array[5] = {9,4,6,2,1};
int sub_arr[3] = {6,2,1};
//...
index = IsSubArr(array,alen,sub_arr,slen);
                 ^^^^^      ^^^^^^^   

第一个参数的类型为int[5],第三个参数的类型为int[3]

因此编译器无法推断出引用的类型T.

如果您要使用带有该功能的数组,那么您可以将其声明为

template <class T, size_t N1, size_t N2> 
int IsSubArr( T ( &a )[N1], T ( &b )[N2] );

或者您可以使用指针而不是对数组的引用

template <class T> int IsSubArr( T *a, size_t a_len, T *b, size_t b_len );

考虑到函数中的这个声明

T& s=a,l=b;

也错了。它等同于以下声明

T& s=a;
T l=b;

这是第一个声明声明对数组的引用,而第二个声明声明一个数组并尝试用另一个数组初始化它。但是,数组没有复制构造函数,编译器将再发出一个错误。并且您可能不会重新分配参考。

您应该知道标题std::search中声明的标准算法<algorithm>可以完成您想要对您的函数执行的工作。

答案 2 :(得分:0)

因为arraysub_arr是两种不同的类型。 array的类型为int[5],而sub_arr的类型为int[3]。数组维度是该类型的一部分。

更改函数以使用两个不同的模板参数,每个数组一个,或使用指针(例如T*

还有另一个错误,如果你继续使用数组和两个不同的模板参数,那么你将继续拥有这个错误,那就是你无法改变引用。一旦您在函数中分配了变量sl,就无法引用其他内容。 sl变量的后一个赋值将失败,因为您尝试将数组彼此分配,而您无法执行此操作,您只能复制数组。

如果您使用指针,那么这不会成为问题。