48

私は理解しようとしていますstd::reference_wrapper

次のコードは、参照ラッパーが参照とまったく同じように動作しないことを示しています。

#include <iostream>
#include <vector>
#include <functional>

int main()
{
    std::vector<int> numbers = {1, 3, 0, -8, 5, 3, 1};

    auto referenceWrapper = std::ref(numbers);
    std::vector<int>& reference = numbers;

    std::cout << reference[3]              << std::endl;
    std::cout << referenceWrapper.get()[3] << std::endl; 
              // I need to use get ^
              // otherwise does not compile.
    return 0;
}

私が正しく理解していれば、暗黙的な変換はメンバー関数の呼び出しには適用されません。これは固有の制限ですか? を頻繁に使用する必要がありstd::reference_wrapper::getますか?

別のケースは次のとおりです。

#include <iostream>
#include <functional>

int main()
{
    int a = 3;
    int b = 4;
    auto refa = std::ref(a);
    auto refb = std::ref(b);
    if (refa < refb)
        std::cout << "success" << std::endl;

    return 0;
}

これは問題なく動作しますが、これをmain定義の上に追加すると、次のようになります。

template <typename T>
bool operator < (T left, T right)
{
    return left.someMember();
}

コンパイラはテンプレートのインスタンス化を試み、暗黙的な変換と組み込み演算子を忘れます。

この動作は固有のものですか、それとも について重要なことを誤解してい std::reference_wrapperますか?

4

1 に答える 1

52

クラスstd::reference_wrapper<T>は、暗黙の変換演算子を次のように実装しT&ます。

operator T& () const noexcept;

より明示的なゲッター:

T& get() const noexcept;

暗黙の演算子は、T(またはT&) が必要な場合に呼び出されます。例えば

void f(some_type x);
// ...
std::reference_wrapper<some_type> x;
some_type y = x; // the implicit operator is called
f(x);            // the implicit operator is called and the result goes to f.

ただし、 aTが必ずしも必要ではない場合もあるため、この場合は を使用する必要がありますget。これは、ほとんどの場合、自動型推定コンテキストで発生します。例えば、

template <typename U>
g(U x);
// ...
std::reference_wrapper<some_type> x;
auto y = x; // the type of y is std::reference_wrapper<some_type>
g(x);       // U = std::reference_wrapper<some_type>

上記some_typeの代わりに取得するには、次のことを行う必要がありますstd::reference_wrapper<some_type>

auto y = x.get(); // the type of y is some_type
g(x.get());       // U = some_type

または、上記の最後の行を に置き換えることもできますg<some_type>(x);。ただし、テンプレート化された演算子 (例: ostream::operator <<()) の場合、型を明示することはできないと思います。

于 2013-08-08T14:11:59.740 に答える