(メンバー) 関数 templateの別のオーバーロード (f(T &)
または など)がない場合、はいわゆる転送参照であり、cv 修飾型の、 またはのいずれかです。しかし、メンバー関数のcv-ref-qualifiersにはそのような規則はありません。has always 右辺値参照修飾子。f(volatile T &&)
template< typename T > f(T &&);
T &&
T
U
U &
U
struct 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-qualifierとcv-ref-qualified型の両方*this
をその本体に示す別のシーケンスが可能です:auto &&
などdecltype(&&)
。
C++17で使用するために準備された、この問題に関する提案はありますか?