C++ C++;<;T>;根据双矢量

C++ C++;<;T>;根据双矢量,c++,C++,我想根据double的向量对T的向量进行排序。也就是说,如果我有 vector<T> a; vector<double>b; 我也不知道如何编写函数体 谢谢 编辑:这是我的算法的用法。我不明白 template <typename T> struct dataPair { dataPair(double s, T o) : m_sortData(s) , m_otherData(o) { } bool o

我想根据double的向量对T的向量进行排序。也就是说,如果我有

vector<T> a;
vector<double>b;
我也不知道如何编写函数体

谢谢

编辑:这是我的算法的用法。我不明白

template <typename T> struct dataPair
{
    dataPair(double s, T o) 
    : m_sortData(s)
    , m_otherData(o)
    {

    }

    bool operator< (const dataPair &rhs) { return (m_sortData < rhs.m_sortData); }

    double m_sortData;
    T m_otherData;

}



  template <class T> vector<T> sortByArrayStuff(vector<T> objects, vector<double> sortNumber) {
    vector<dataPair<T>> v;
    for (unsigned int i = 0; i < objects.size(); i++) {
        v.push_back(dataPair<T>(objects[i], sortNumber[i]));
    }
    sort(v.begin(), v.end());
    vector<T> retVal;

    for (unsigned int i = 0; i < objects.size(); i++) {
        retVal.push_back(dataPair<T>(objects[i], sortNumber[i]));
    }
    return retVal;
};
模板结构数据对
{
数据对(双s,T o)
:m_sortData(s)
,m_其他数据(o)
{
}
布尔运算符<(常量数据对和rhs){return(m_sortData
我想对“点”向量和“点”向量使用相同的模板:

向量分类器;
矢量分类点=分类点(点、分类点);
向量分类的轮廓=分类的轮廓(轮廓、分类的轮廓);
错误是

cannot convert parameter 1 from 'dataPair<T>' to 'cv::Point &&'
          with
          [
              _Ty=cv::Point
          ]
          and
          [
              T=cv::Point
          ]
          Reason: cannot convert from 'dataPair<T>' to 'cv::Point'
          with
          [
              T=cv::Point
          ]
无法将参数1从“数据对”转换为“cv::Point&”
具有
[
_Ty=cv::点
]
和
[
T=cv::点
]
原因:无法从“数据对”转换为“cv::Point”
具有
[
T=cv::点
]

您应该做的是创建一个
结构
,如下所示:

template <typename T> struct dataPair
{
    dataPair(double s, T o) 
    : m_sortData(s)
    , m_otherData(o)
    {

    }

    bool operator< (const dataPair &rhs) { return (m_sortData < rhs.m_sortData); }

    double m_sortData;
    T m_otherData;

}
}

编辑:有一些打字错误

EDIT2:为了提高效率,你也可以使用函子,但这是最基本的想法


EDIT3:

我能想到的最简单的方法是,如果您在T的类声明中包含double,并将其用作排序参数。抱歉,如果我的模板语法不是很好,我已经有一段时间没有使用它们了:

class YourClass
{
  //Some stuff...
  double sortVal;
};

bool std::less<YourClass>(YourClass left, YourClass  right)
{
   return left.sortVal < right.sortval;
}
classyourclass
{
//一些东西。。。
双索塔尔;
};
bool std::less(YourClass left,YourClass right)
{
返回left.sortVal
前几天我刚做了类似的事情,这是我的想法。将两个向量合并成一个多重贴图。排序将自动完成,只需将它们插入地图,然后将它们从地图提取回向量。我为这项工作提供了两个功能模板,它们是:

// This function basically does the reverse of a transform.  Whereas transform takes
// two inputs and by some method merges them into one, this function takes one input
// and by some method splits it in two.
template<typename InIt, typename Out1It, typename Out2It, typename Fn>
void fork_transform(InIt ibegin, InIt iend, Out1It o1begin, Out2It o2begin, Fn fork)
{
    while(ibegin != iend)
    {
        fork(*ibegin, *o1begin, *o2begin);
        ++o1begin;
        ++o2begin;
        ++ibegin;
    }
}

template<typename ItPrimary, typename ItSecondary>
void simul_sort(ItPrimary begin1, ItPrimary end1, ItSecondary begin2)
{
    typedef std::iterator_traits<ItPrimary>::value_type T1;
    typedef std::iterator_traits<ItSecondary>::value_type T2;

    typedef std::multimap<T1,T2> Map_t;
    typedef Map_t::value_type Pair_t;

    Map_t m;

    // this was necessary for me because of a bug in VC10, see my most recent question
    auto MakePair = [](const T1 & first, const T2 & second) { return std::make_pair(first,second); };
    std::transform(begin1, end1, begin2, std::inserter(m,m.begin()), MakePair);

    auto Fork = [](const Pair_t & p, T1 & first, T2 & second) { first = p.first; second = p.second; };
    fork_transform(m.begin(), m.end(), begin1, begin2, Fork);
}

如果您需要该问题的通用解决方案,请查看以下其中一个答案中的拉链模板:


您将需要一些类似于拉链的东西—一些将两个序列压缩成一个序列的实体。

这里有一个通用解决方案—一个将索引向量返回到数组中的函数。您可以在
a
b
上使用这些索引来按排序顺序获取它们

template<class RandomAccessIterator>
struct IndirectCompare : public std::binary_function<size_t, size_t, bool>
{
    IndirectCompare(RandomAccessIterator first) : m_first(first)
    {
    }
    bool operator()(const size_t &left, const size_t &right)
    {
        return *(m_first + left) < *(m_first + right);
    }
    RandomAccessIterator m_first;
};

template<class RandomAccessIterator>
std::vector<size_t> ordered_index(RandomAccessIterator first, RandomAccessIterator last)
{
    size_t n = last - first;
    std::vector<size_t> result;
    result.reserve(n);
    for (size_t i = 0;  i < n;  ++i)
        result.push_back(i);
    IndirectCompare<RandomAccessIterator> comp(first);
    std::sort(result.begin(), result.end(), comp);
    return result;
}
模板
struct IndirectCompare:public std::binary_函数
{
间接比较(RandomAccessIterator优先):m_优先(优先)
{
}
布尔运算符()
{
返回*(m_first+left)<*(m_first+right);
}
随机访问迭代器m_优先;
};
模板
向量有序索引(首先是RandomAccessIterator,最后是RandomAccessIterator)
{
大小n=最后一个-第一个;
std::向量结果;
结果:储备量(n);
对于(尺寸i=0;i

另外,我现在已经测试了这段代码,它可以工作。

如果你想同时对两个向量进行排序,你应该创建一个std::vector(比如c)的std::pair第一个组件必须是正常排序的组件,第二个组件必须是相应排序的组件。

std::vector<std::pair<double, T>> c;
std::sort(c.begin(), c.end());
std::向量c;
排序(c.begin(),c.end());

希望这有帮助。

您的
a
b
与您的结果之间有什么关系?我好像找不到。不要写新函数。编写一个比较器,提供给
std::sort
。(但您的意思是
模板
,并且可能应该接受那些函数参数作为
引用到常量
)。您希望最终结果是什么样的?您的错误可能是由于将retVal声明为
向量
,但试图将
数据对
推入其中。我想你需要
retVal.push_back(v[I].m_otherData)
。为什么不使用
std::pair
并编写一个函子呢?更容易消化,正如你所说,更有效。是的,很好。这是相同的概念,STL已经完成了
pair
,所以这也很好。你能展示一下函子版本的样子吗?我需要从std::pair继承并定义运算符吗
// This function basically does the reverse of a transform.  Whereas transform takes
// two inputs and by some method merges them into one, this function takes one input
// and by some method splits it in two.
template<typename InIt, typename Out1It, typename Out2It, typename Fn>
void fork_transform(InIt ibegin, InIt iend, Out1It o1begin, Out2It o2begin, Fn fork)
{
    while(ibegin != iend)
    {
        fork(*ibegin, *o1begin, *o2begin);
        ++o1begin;
        ++o2begin;
        ++ibegin;
    }
}

template<typename ItPrimary, typename ItSecondary>
void simul_sort(ItPrimary begin1, ItPrimary end1, ItSecondary begin2)
{
    typedef std::iterator_traits<ItPrimary>::value_type T1;
    typedef std::iterator_traits<ItSecondary>::value_type T2;

    typedef std::multimap<T1,T2> Map_t;
    typedef Map_t::value_type Pair_t;

    Map_t m;

    // this was necessary for me because of a bug in VC10, see my most recent question
    auto MakePair = [](const T1 & first, const T2 & second) { return std::make_pair(first,second); };
    std::transform(begin1, end1, begin2, std::inserter(m,m.begin()), MakePair);

    auto Fork = [](const Pair_t & p, T1 & first, T2 & second) { first = p.first; second = p.second; };
    fork_transform(m.begin(), m.end(), begin1, begin2, Fork);
}
simul_sort(b.begin(), b.end(), a.begin());
template<class RandomAccessIterator>
struct IndirectCompare : public std::binary_function<size_t, size_t, bool>
{
    IndirectCompare(RandomAccessIterator first) : m_first(first)
    {
    }
    bool operator()(const size_t &left, const size_t &right)
    {
        return *(m_first + left) < *(m_first + right);
    }
    RandomAccessIterator m_first;
};

template<class RandomAccessIterator>
std::vector<size_t> ordered_index(RandomAccessIterator first, RandomAccessIterator last)
{
    size_t n = last - first;
    std::vector<size_t> result;
    result.reserve(n);
    for (size_t i = 0;  i < n;  ++i)
        result.push_back(i);
    IndirectCompare<RandomAccessIterator> comp(first);
    std::sort(result.begin(), result.end(), comp);
    return result;
}
std::vector<std::pair<double, T>> c;
std::sort(c.begin(), c.end());