首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将一个functor传递给functor

将一个functor传递给functor
EN

Stack Overflow用户
提问于 2011-02-04 02:31:32
回答 3查看 318关注 0票数 2

我正在尝试编写一个可以传递给std::sort的函数器,它将根据向量中对象的比较对表示另一个对象向量的索引的向量进行排序。我不想假设向量中的对象有一个成员排序,而是希望传入一个谓词,比如如果我直接对对象的向量进行排序,我会传递给std::operator<。

代码语言:javascript
复制
template <class T, class _Pr>
class SortIndexVectorObjectsHelper : public std::binary_function<ULONG, ULONG, bool>
{
    ULONG m_ulSize;
    std::vector<T> & m_aItems;
    BOOL m_bSortAscending;
    _Pr m_Comp;

public:

    SortIndexVectorObjectsHelper(std::vector<T> & aItems, _Pr Comp) : m_aItems(aItems), m_Comp(Comp), m_ulSize(0)
    {
        m_ulSize = m_aItems.size();
    }

    bool operator()( ULONG & rLeft, ULONG & rRight) 
    {
        if (rLeft < m_ulSize && rRight < m_ulSize)
        {
            T & pLeft = m_aItems[rLeft];
            T & pRight = m_aItems[rRight];

            if (pLeft && pRight)
            {
                return m_Comp(pLeft, pRight);
            }
        }
        return false;
    }


};

struct SortFooByX: public std::binary_function<CFoo,CFoo, bool>
{
    BOOL m_bSortAscending;

    SortFooByX(BOOL bSortAscending)
    {
        m_bSortAscending = bSortAscending;
    }

    bool operator()( CFoo & _Left,  CFoo & _Right) 
    {

         if (m_bSortAscending)
         {
        if (_Left.X() < _Right.X())
           return true;
         }
         else
         {
        if (_Left.X() > _Right.X()) 
                   return true;

          }

          return false;
    }


};

std::sort(aFooIndicies.begin(), aFooIndicies.end(), SortIndexVectorObjectsHelper<CFoo, std::binary_function<CFoo, CFoo, bool> >(aFoo, SortFooByX(FALSE)));

编译这个代码会给我一个错误,两个重载都不能转换所有的参数类型。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-04 03:01:27

代码语言:javascript
复制
std::sort(aFooIndicies.begin(), aFooIndicies.end(), SortIndexVectorObjectsHelper<CFoo, std::binary_function<CFoo, CFoo, bool> >(aFoo, SortFooByX(FALSE)));

SortIndexVectorObjectsHelper中的第二个类型参数错误。类型应为SortFooByX,如下所示:

代码语言:javascript
复制
SortIndexVectorObjectsHelper<CFoo, SortFooByX> comparer(aFoo, SortFooByX(FALSE));
std::sort(aFooIndicies.begin(), aFooIndicies.end(), comparer);

尝尝这个。它现在应该可以工作了。

票数 0
EN

Stack Overflow用户

发布于 2011-02-04 03:03:18

比较运算符需要接受常量引用。常量引用不能隐式转换为非常数引用,因此编译器表示没有与参数类型匹配的有效重载。只需使用下面的代码:

代码语言:javascript
复制
bool operator()( const ULONG & rLeft, const ULONG & rRight)

我建议您在比较CFoo和CFoo的另一个类中执行相同的操作。当您编写一个通过引用获取参数并且不修改这些参数的值的函数时,最好始终将引用常量设置为常量,这样会更清晰、更安全、限制更少。当它们是非常数时,你告诉世界你希望这些参数是可修改的,而实际上它们不需要修改,所以你限制了函数的可能使用,在这种情况下,这导致了问题。

正如其他人也提到的,您应该小心您的命名约定。通常,您应该避免使用前导下划线_,因为它们经常用于特殊的保留字或关键字(双前导下划线通常用于编译器特定指令等的保留字)。最好避免它,否则,您最终可能会遇到非常奇怪的bug或可移植性问题。

票数 0
EN

Stack Overflow用户

发布于 2011-02-04 03:04:34

代码语言:javascript
复制
template<class Lookup, class Compare>
struct LookupCompare {
  Lookup &lookup;
  Compare cmp;

  LookupCompare(Lookup &lookup, Compare cmp=Compare()) : lookup (lookup), cmp (cmp) {}

  template<class T>
  bool operator()(T const &a, T const &b) {
    return cmp(lookup[a], lookup[b]);
  }
};

Example

代码语言:javascript
复制
struct Less {
  template<class T>
  bool operator()(T const &a, T const &b) {
    return std::less<T>()(a, b);
  }
};

template<class Lookup>
LookupCompare<Lookup, Less> lookup_compare(Lookup &lookup) {
  return lookup;
}
template<class Lookup, class Compare>
LookupCompare<Lookup, Compare> lookup_compare(Lookup &lookup, Compare cmp) {
  return LookupCompare<Lookup, Compare>(lookup, compare);
}

int main() {
  vector<int> lookup;
  lookup.push_back(42);
  lookup.push_back(3);
  lookup.push_back(5);

  vector<int> data;
  data.push_back(0);
  data.push_back(1);
  data.push_back(2);

  cout << data << '\n';
  sort(data.begin(), data.end(), lookup_compare(lookup));
  cout << data << '\n';

  return 0;
}

我不确定你为什么要使用m_ulSize,所以我把它省略了。我也做了相当大的简化,现在LookupCompare可以运行在10SLOC上。特别是,它不需要升序标志,因为您可以将std::less替换为std::need或注入一个“反转”比较器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4890167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档