Проблема несколько надумана (на самом деле ее нет=)), но все же. Бывает так, что нужно сравнить динамический массив со статическим (размер которого заранее известен). Например, со строкой вида
char szSTRING[] = "wonderful string";
Можно написать нечто вроде:
void Func(char const *psz, size_t nLen)
{
if (sizeof(szSTRING) <= nLen + 1) {
if (psz[0] == 'w'
&& psz[0] == 'o'
&& psz[1] == 'n'
&& psz[2] == 'd'
&& psz[3] == 'e'
&& psz[4] == 'r'
&& psz[5] == 'f'
&& psz[6] == 'u'
&& psz[7] == 'l'
&& psz[8] == ' '
&& psz[9] == 's'
&& psz[10] == 't'
&& psz[11] == 'r'
&& psz[12] == 'i'
&& psz[13] == 'n'
&& psz[14] == 'g')
{
// че-то делаем...
}
}
}
а можно и не париться:
void Func(char const *psz, size_t nLen)
{
if (::strncmp(szSTRING, psz,nLen) == 0) {
// че-то делаем...
}
}
Но мы ведь ищем легких путей!
Поэтому делаем "совсем с обратной стороны":
#include <iostream>
#include <algorithm>
using namespace std;
// [url=http://rsdn.ru/Forum/Message.aspx?mid=265122&only=1]товарищ[/url]дал стране угля:
template< class T, size_t N > char (&LengthOf (T(&)[N]) )[N];
#define length_of(arr) sizeof(LengthOf(arr)) \
/**/
#if !defined(_MSC_VER)
# define __forceinline inline
#endif
//////////////////////////////////////////////////////////////////////////
// FindMismatch - generalized mismatch search
//
template< class T, size_t t_nCount, size_t t_nStart = 0 >
struct FindMismatch
{
enum { IDX = t_nStart + t_nCount - 1 };
typedef T const * const ArrayT;
__forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
{
//cout << "IDX == " << IDX << endl
// << "\tlhs[IDX] == " << lhs[IDX] << endl
// << "\trhs[IDX] == " << rhs[IDX] << endl
// << flush;
return lhs[IDX] == rhs[IDX] ?
FindMismatch< T, t_nCount - 1, t_nStart >::Do(lhs, rhs) : IDX;
}
};
template< class T, size_t t_nStart >
struct FindMismatch< T, 1, t_nStart >
{
typedef T const * const ArrayT;
__forceinline static size_t Do(ArrayT lhs, ArrayT rhs)
{
//cout << "IDX == " << t_nStart << endl
// << "\tlhs[t_nStart] == " << lhs[t_nStart] << endl
// << "\trhs[t_nStart] == " << rhs[t_nStart] << endl
// << flush;
return lhs[t_nStart] == rhs[t_nStart] ? (size_t)-1 : t_nStart;
}
};
//////////////////////////////////////////////////////////////////////////
// ArrayStuff
//
template< class CharT = char >
struct ArrayStuff
{
template< size_t N >
__forceinline static size_t Compare(CharT const *pStr, CharT const (&symb_arr)[N])
{
enum { LEN = length_of(symb_arr) - 1 };
return FindMismatch< CharT, LEN >::Do(pStr, symb_arr);
}
template< size_t t_nIdx, class T, template <class T1, size_t, size_t> class HasDo >
struct RT2CT
{
typedef T const * const ArrayT;
__forceinline static size_t Get(size_t n, ArrayT lhs, ArrayT rhs)
{
return n < t_nIdx ?
RT2CT< t_nIdx - 1, T, HasDo >::Get(n, lhs, rhs)
: HasDo< T, t_nIdx, 0 >::Do(lhs, rhs);
}
};
template< class T, template <class T1, size_t, size_t> class HasDo >
struct RT2CT<1, T, HasDo >
{
typedef T const * const ArrayT;
__forceinline static size_t Get(size_t n, ArrayT lhs, ArrayT rhs)
{
return n == 1 ?
HasDo< T, 1, 0 >::Do(lhs, rhs) : (size_t)-1;
}
};
template< size_t N >
__forceinline static int Compare(CharT const *pStr, size_t nLen, CharT const(&symb_arr)[N])
{
enum { LEN = length_of(symb_arr) - 1 };
if (nLen < LEN) {
//cout << "!!! nLen (" << nLen << ") < LEN (" << LEN << ") !!! " << endl;
return RT2CT< LEN, CharT, FindMismatch >::Get(nLen, pStr, symb_arr);
}
else {
return FindMismatch<CharT, LEN >::Do(pStr, symb_arr);
}
}
};
int main()
{
char const *pstr = "abcdef";
cout << "ArrayStuff<char>::Compare(\""<< pstr <<"\", \"abcdeF\") == "
<< ArrayStuff<char>::Compare(pstr, "abcdeF") << endl
<< flush;
cout << "ArrayStuff<char>::Compare(\""<< pstr <<"\", 3, \"abcQWE\") == "
<< ArrayStuff<char>::Compare(pstr, 3, "abcQWE") << endl
<< flush;
::system("PAUSE");
return 0;
}