11

(メンバー) 関数 templateの別のオーバーロード (f(T &)または など)がない場合、はいわゆる転送参照であり、cv 修飾型の、 またはのいずれかです。しかし、メンバー関数のcv-ref-qualifiersにはそのような規則はありません。has always 右辺値参照修飾子。f(volatile T &&)template< typename T > f(T &&);T &&TUU &Ustruct S { void f() && { ; } };S::f()

volatile一般的なコードでは、すべてのメンバー関数が一般的に同じことを行う場合に、メンバー関数の 4 つ (または修飾子も考慮すると 8 つ) のオーバーロードの定義を避けることが非常に便利です。

この方法で発生するもう 1 つの問題は、特定の意味で有効なcv-ref-qualifierを定義することが不可能であるということです。次のコードでは、メンバー関数のref-qualifierがofである*thisかどうかを判断できません。operator ()&&&

#include <type_traits>
#include <utility>
#include <iostream>

#include <cstdlib>

#define P \
{                                                                       \
    using this_ref = decltype((*this));                                 \
    using this_type = std::remove_reference_t< this_ref >;              \
    std::cout << qual() << ' '                                          \
              << (std::is_volatile< this_type >{} ? "volatile " : "")   \
              << (std::is_const< this_type >{} ? "const " : "")         \
              << (std::is_lvalue_reference< this_ref >{} ? "&" : "&&")  \
              << std::endl;                                             \
}

struct F
{
    constexpr int qual() & { return 0; }
    constexpr int qual() const & { return 1; }
    constexpr int qual() && { return 2; }
    constexpr int qual() const && { return 3; }
    constexpr int qual() volatile & { return 4; }
    constexpr int qual() volatile const & { return 5; }
    constexpr int qual() volatile && { return 6; }
    constexpr int qual() volatile const && { return 7; }
    void operator () () & P
    void operator () () const & P
    void operator () () && P
    void operator () () const && P
    void operator () () volatile & P
    void operator () () volatile const & P
    void operator () () volatile && P
    void operator () () volatile const && P
};

int
main()
{
    {
        F v;
        F const c{};
        v();
        c();
        std::move(v)();
        std::move(c)();
    }
    {
        volatile F v;
        volatile F const c{};
        v();
        c();
        std::move(v)();
        std::move(c)();
    }
    return EXIT_SUCCESS;
}

しかし、上記の構文があれば、とてもいいでしょう。つまり、 のdecltype((*this))正確なcv-ref 修飾型を示し*thisます。私の考えでは、 C++標準の今後のバージョンにこのような構文を導入することは、重大な変更ではありません。しかし&&cv-ref-qualifier の転送は (そして、委員会 (つまり、コア言語ワーキング グループ) の省略のように見えます)。

メンバー関数cv-ref-qualifiercv-ref-qualified型の両方*thisをその本体に示す別のシーケンスが可能です:auto &&などdecltype(&&)

C++17で使用するために準備された、この問題に関する提案はありますか?

4

1 に答える 1