将索引数组排序为主数组



我正在编写一个C++dll来对从VBA传递的SAFEARRAY进行排序。

我没有使用任何OLE库,而是直接访问数组描述符和数据。

对任何本机VBA类型的数组进行排序都没有问题。例如,以下片段对BSTR数组进行排序:

long * p = (long*)pData; 
std::sort(p, p + elems, comparestring);

它使用这个比较函数:

bool comparestring(const long& lhs, const long& rhs) {
   wchar_t * lhs_ = (wchar_t*)lhs;
   wchar_t * rhs_ = (wchar_t*)rhs;
   return _wcsicmp(lhs_, rhs_) < 0;
}

我意识到我在这里作弊,因为wchar_tBSTR非常不同,但在Excel字符串的有效载荷中使用零字符并不常见,所以我对此没意见。以上操作效果良好。

问题

我希望dll能够选择性地将索引的伴随数组排序到主数据数组中。在这种模式下,只对索引数组进行排序,而不影响源数据。

我的研究表明,λ函子可能是最有前途的路径,因为我不愿意为额外的数据数组或向量或对分配内存。

特别是,这个答案似乎很有希望。

然而,我不知道如何将其适应我处理从pData开始的BSTR的原始指针的情况。

我尝试过以下几种:

long * p = (long*)pData; 
long ndx[5];
for (int i = 0; i < 5; i++) ndx[i] = i + 1;
std::sort(ndx[0], ndx[4], [&p](long i1, long i2) { comparestring((*p) + i1, (*p) + i2); })

我正在使用VC++2015和上述结果在以下错误:

Error C2893 Failed to specialize function template 'iterator_traits<_Iter>::iterator_category std::_Iter_cat(const _Iter &)'

我的C编程时代是古老的历史(早于C++的存在),所以我有点挣扎。感谢您的帮助。

更新

代码现在看起来是这样的。。并编译,但执行后ndx的顺序不正确:

long * p = (long*)pData; 
long ndx[5];
for (int i = 0; i < 5; i++) ndx[i] = i + 1;
std::sort(ndx, ndx + 5, [&p](long i1, long i2) { return comparestring(*p + i1, *p + i2); })

此代码:

long ndx[5];
for (int i = 0; i < 5; i++) ndx[i] = i + 1;
std::sort(ndx[0], ndx[4], [&p](long i1, long i2) { comparestring((*p) + i1, (*p) + i2); })

应该是:

long ndx[5];
for (int i = 0; i < 5; i++) ndx[i] = i;
std::sort(ndx, ndx + 5, [&](long i1, long i2) { return comparestring(*(p + i1), *(p + i2)); }

std::sort的前两个参数是迭代器范围。最好使用std::begin(ndx)std::end(ndx)(假设编译器与C++11兼容)。

此外,第二行可以写入std::iota( std::begin(ndx), std::end(ndx), 0 );

最新更新