over 3 years ago

今天有一個物件的vector,此物件擁有一個變數density,我們想要依照他的density大小來依序存取。但基於某些理由不適合直接排序vector,也不適合用物件們的reference另外來排序。所以只使用物件在vector裡的index加上奇怪的functor來進行排序(我想不到其他的方法了ORZ)

Obj.h
class Obj
{
public:
  double density;
};

struct comp
{// comparator for objs index
  comp(const vector<Obj> &p_obj): obj_(p_obj) {}
  bool operator()(const size_t p_index_1, const size_t p_index_2)
  {
    return obj_[p_index_1].density < obj_[p_index_2].density;
  }
private:
  const vector<Obj> &obj_;
};
main.cpp
int main()
{
  vector<Obj> objs;
  // initialize and fill up objs
  // ...
  vector<size_t> obj_indexs(objs.size());
  for(size_t it = 0; it < obj_indexs.size(); ++it)
  {
    obj_indexs[it] = it;
  }

  // case 1: sort index by compare density of obj
  sort(objs.begin(), objs.end(), comp(objs)); // OK.
  
  return 0;
}

但假如今天改成使用set來維持density的大小關係,並且直接把functor塞進去就會產生error。主因是C++ compiler對於set<size_t, comp> obj_set(comp(objs));這個表示式的解讀跟我們的直覺想法是不同的。簡單說就是他把obj_set(comp(objs))當成funciton declaration,前面的set<size_t, comp>當成function的回傳值,詳細看wiki的例子比較簡單且清楚。
所以要改成第二種先把要用functor定義出來在丟給set的constructor。

參考 wiki 有例子↓
http://en.wikipedia.org/wiki/Most_vexing_parse

main.cpp
  // case 2: 
  //set<size_t, comp> obj_set(comp(objs)); // incorrect.
  
  comp density_comparator(objs);
  set<size_t, comp> obj_set(density_comparator); // OK.
  
  // set operation
  obj_set.inset(0); // Error in first declaration
  
← [交換] 慕尼黑學制 - 碩班 慕尼黑 租房整理 →