如果(成员)函数模板没有其他重载(例如,f(T &)
或) ,那么就是所谓的转发引用,并且是,或者对于某些cv 限定类型。但是对于成员函数的cv-ref-qualifiers没有这样的规则。在一个总是右值引用限定符中。f(volatile T &&)
template< typename T > f(T &&);
T &&
T
U
U &
U
struct S { void f() && { ; } };
S::f()
volatile
在泛型代码中,避免定义某些成员函数的 4 个(甚至 8 个,如果我们还考虑限定符)重载是非常有用的,以防它们都做同样的事情。
以这种方式出现的另一个问题是,在特定意义上定义有效的cv-ref-qualifier是不可能的。*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-qualified类型*this
。在我看来,将这样的语法引入到即将到来的C++标准版本中并不是一个重大改变。但是&&
作为转发 cv-ref-qualifier是(而且它看起来像是委员会的遗漏(即核心语言工作组))。
另一个序列可以在其主体中表示成员函数cv-ref-qualifier和cv-ref-qualified类型:等。*this
auto &&
decltype(&&)
是否有关于此问题的提案,准备在C++17中使用?