2006/07/01

tr1::reference_wrapper

好久以前就知道 TR1,但一直到讀了《Effective C++, 3/e》才正式開始看 TR1。先前對 unordered_mapunordered_setshared_ptr 早有耳聞,應不需要費太多工夫。翻開 TR1 (Draft),第一個遇上的是 tr1::reference_wrapper,顧名思義,這種 object 外覆於 references(不過內部實作應該是用指標:reference_wrapper 支援 copy assignment operator),使 reference 成為「第一級物件」(first class objects),而可置於容器內。這是我寫的測試碼:

#include <tr1/functional>

#include <iterator>
#include <iostream>
#include <vector>

using namespace std;

int main() {
  int i = 0, j = 0, k = 0;

  // "angle-bracket hack" has not yet been supported
  vector<tr1::reference_wrapper<int> > v;
  v.push_back(tr1::ref(i));  // helper function
  v.push_back(tr1::ref(j));  // of tr1::reference_wrapper
  v.push_back(tr1::ref(k));
  
  i = 2; j = 3; k = 1;
  copy(v.begin(), v.end(), ostream_iterator(cout, " "));
  cout << endl;  // 2 3 1

  sort(v.begin(), v.end());
  copy(v.begin(), v.end(), ostream_iterator(cout, " "));
  cout << endl;  // 1 2 3

  i = 4; j = 6; k = 5;
  copy(v.begin(), v.end(), ostream_iterator(cout, " "));
  cout << endl;  // 5 4 6

  sort(v.begin(), v.end(), greater());
  copy(v.begin(), v.end(), ostream_iterator(cout, " "));
  cout << endl;  // 6 5 4
}

reference_wrapper<T> 看來也和 tr1::function 有點關係,我猜當 T 為某種 callable type 時(e.g. plain functions, member functions, function objects),reference_wrapper 也類似 tr1::function。繼續往下,看看這個猜測的準確度如何。

喔,對了,在 tr1::enable_shared_from_this 看到熟悉的手法:CRTP(curiously-recurring template pattern)。我猜是想藉以實現侵入式計數(intrusive counting)或其他侵入式手法。在還沒看源碼之前,多猜猜也滿有意思的 :P。

--
我還沒睡 XD。


回覆(直接在下面回的話,沒有<code>、沒有<pre>,縮排太麻煩了 XD):

> tr1::reference_wrapper似乎是一種smart reference ?

應該只是單純的 wrapper 而已,因為它不做什麼資源管理。

for_each 是對區間內每個元素施用「作為第三引數傳入的那個 unary function object」,所以如果要用 for_each,應該會變成類似這樣:

template<typename Arg>
// or make Printer a plain class
// and make operator() a member template
class Printer: public unary_function<Arg, void> {
public:
    Printer(ostream& a, const char* b = 0):
        os(a), tail(b) { }
    void operator()(const Arg& arg) const {
        os << arg << tail;
    }
private:
    ostream& os;  // os & tail can also be templatized
    const char* const tail;
};

// ...
vector<int> v;
// ...
for_each(v.begin(), v.end(), Printer<int>(cout, " "));

Blogger yen37/02/2006 4:24 am 說:

看懂歸看懂....

tr1::reference_wrapper似乎是一種smart reference ?

這樣子的特性,我不是很有研究,但應該可避免許多不必要錯誤,哈,我等會再看書

話說,問一個比較簡單的問題
copy(v.begin(),v.end(),ostream_iterator(cout," "));
是這樣子寫

如果使用for_each
void output(){ ... }
for_each(v.begin(),v.end(),output);

再另外寫一個function obeject ?
還是說,for_each 也可以使用ostream_iterator?

哈哈,我反而在問微末細節

 
Blogger yen37/02/2006 5:28 am 說:

漂亮的程式碼,漂亮的回覆
謝謝你啦(^_^)

繼續努力去

 
Blogger yen37/04/2006 4:05 pm 說:

補充一下,現在發現
原來wrapper是包覆的意思
所以不一定會包括資源管理

 

<< 回到主頁