2

私は、C++ 参照のように動作するクラスを設計していますが、いくつかの余分な機能 (簿記) を行います。

std::reference_wrapper<T>最初は良いモデルだと思いました。しかし、しばらくしてstd::reference_wrapper<T>、割り当てが内部ポインターを再バインドするため、原則としても C++ 参照として動作しないことに気付きました。

    double a = 5.;
    double b = 3.;
    double& ref = a;
    ref = b;
    assert(&ref != &b); // ref is not bound to b
    std::reference_wrapper<double> refwpr = a;
    refwpr = b;
    assert(&refwpr.get() == &b); // ref wrapper was rebound to b

もちろん、自分のクラスの動作を変更することはできますが (再バインドしないように)、参照をエミュレートするクラスが既に存在する可能性があります。たとえば、「std::real_reference<T>」のようなもの。

参照をより厳密にエミュレートするクラス (標準かどうか) はありますか?

これも役立つと思います。たとえば、多くの場所で std::vector<std::reference_wrapper<T>>の代替として提示されているstd::vector<T&>ことがわかりますが、セマンティクスは異なりますが、いくつかの変更で実現できるため、これは誤解を招く可能性がありますstd::vector<std::real_reference<T>>


「完璧な」参照ラッパーが可能であれば、参照はポインターで実装でき、必要はなく、すべての点でまったく同じようにT& 機能するライブラリ機能が必要になるだけだと思います....reference<T>T&

...つまり、言語を使用すると、型に属性を「オーバーロード」して&、言語参照の代わりにカスタム型を生成できることを意味します。たとえばusing mytype& = custom_reference_emulator_of_mytype

4

1 に答える 1

2
template <typename T>
class Tref {
    std::tuple<T &> t;
public:
    template <typename... Args>
    Tref(Args&&... args): t(std::forward<Args>(args)...) {}
    operator T &() { return std::get<0>(t); }
    decltype(&std::get<0>(t)) operator&() { return &std::get<0>(t); }
};


Tref<double &> t(a);
t = b;
assert(&t != &b);

std::reference_wrapperテンプレートが参照を消去すると、バインディングが行われます。ニーズを満たすためにクラスを構築する必要はなく、通常の参照を使用するだけです。(はっきりと説明できないかもしれません。私の英語は下手です。)

于 2015-12-12T14:58:20.453 に答える