2010-12-01 6 views
7

いつものように、コード:C++ 98ではC++で完璧な転送を行うと、reference_wrapperは非推奨になりますか?最初

#include <functional> 

using namespace std; 
using namespace std::tr1; 

void f(int& r) { r++; } 

template<class F, class P> void g1(F f, P t) { f(t); } 
template<class F, class P> void g2(F f, P&& t) { f(forward<P>(t)); } 

int main() 
{ 
    int i = 0; 

    g1(f, ref(i)); // old way, ugly way 
    g2(f, i); // new way, elegant way 
} 

は、我々はテンプレート関数によってパラメータを前方pefectするための良い方法はありません。だからC++の達人はその目的を達成するためにrefとcrefを発明しました。

r値参照と完璧な転送ができたので、refやcrefなどを非推奨にする必要がありますか?

答えて

3

参照ラッパーは依然として有効です。これは、物事を保管する場合です。例えば、基準ラッパーであなたはmake_tupleとstd ::スレッドは、それらをコピーするのではなく、いくつかの引数を参照するオブジェクトを作成:: STDを行うことができます。

class abstract_job 
{ 
public: 
    virtual ~abstract_job() {} 
    virtual void run() = 0; 
}; 

class thread 
{ 
public: 
    template<class Fun, class... Args> 
    thread(Fun&& f, Args&&... args) 
    { 
     typedef typename decay<Fun>::type fun_type; 
     typedef decltype(make_tuple(forward<Args>(args)...)) tuple_type; 
     unique_ptr<abstract_job> ptr (new my_job<fun_type,tuple_type>(
      forward<Fun>(fun), 
      make_tuple(forward<Args>(args)...) 
     )); 
     // somehow pass pointer 'ptr' to the new thread 
     // which is supposed to invoke ptr->run(); 
    } 
    ... 
}; 

... 

void foo(const int&); 

int main() 
{ 
    thread t (foo, 42); // 42 is copied and foo is invoked 
    t.join()   // with a reference to this copy 
    int i = 23; 
    thread z (foo, std::cref(i)); // foo will get a reference to i 
    z.join(); 
} 

make_tuple(std::ref(i)) // yields a tuple<int&> 
make_tuple(  i) // yields a tuple<int> 

乾杯ことに注意してください! s

2

これは、reference_wrapperとしています。むしろ、関数オブジェクトを参照によって渡すことができるのは、通常は値によって受け入れられるという点です。あなたが代わりにT&&と引数を取るならば、値渡しが不可能になることを意味しないでしょうか?

#include <iostream> 
#include <functional> 
#include <algorithm> 

class X: public std::unary_function<int, void> 
{ 
    int n; 
public: 
    X(): n(0) {} 
    void operator()(int m) {n += m;} 
    int get_n() const { return n; } 
}; 

template <class Iter, class Fun> 
void for_each(Iter from, Iter to, Fun&& fun) 
{ 
    for (; from != to; ++from) 
     fun(*from); 
} 

int main() 
{ 
    int a[] = {1, 2, 3}; 
    X x1; 
    ::for_each(a, a + 3, x1); 
    std::cout << x1.get_n() << '\n'; //6 

    X x2; 
    std::for_each(a, a + 3, x2); 
    std::cout << x2.get_n() << '\n'; //0 

    X x3; 
    std::for_each(a, a + 3, std::ref(x3)); 
    std::cout << x3.get_n() << '\n'; //6 
} 
関連する問題