C++0x 右辺値参照 std::forward

前回、std::moveを紹介したが、右辺値参照のためにはもう1つ
std::forwardが用意される

namespace std {
    template <class T>
    struct identity {
        typedef T type;
    };

    template <class T>
    inline T&& forward(typename identity<T>::type&& x)
    {
        return x;
    }
}

まず、右辺値参照(&&)では、参照値(&)も受け取ることができる
これがバグの温床になってしまうことがある

struct hoge {
    hoge(int&) {}
};

template <class T, class A>
shared_ptr<T> factory(A&& a)
{
    return shared_ptr<T>(new T(a));
}

int main()
{
    shared_ptr<hoge> p1 = factory<hoge>(3); // OK...エラーになってほしかった

    int value = 3;
    shared_ptr<hoge> p2 = factory<hoge>(value); // OK

    return 0;
}

std::forwardを使用することで、右辺値参照で受け取った値を安全に転送することができる

struct hoge {
    hoge(int&) {}
};

template <class T, class A1>
shared_ptr<T> factory(A1&& a1)
{
    return shared_ptr<T>(new T(forward<A1>(a1)));
}

int main()
{
    shared_ptr<hoge> p1 = factory<hoge>(3); // エラー!

    int value = 3;
    shared_ptr<hoge> p2 = factory<hoge>(value); // OK

    return 0;
}

↓によると、「完璧な転送」だそうな


N2027 - A Brief Introduction to Rvalue References

右辺値参照・ムーブセマンティクス

C++0x言語拡張まとめ