转发成员函数的cv-ref-qualifier

Ori*_*ent 11 c++ member-functions c++11 ref-qualifier c++17

如果没有另一个超载(比如,f(T &)f(volatile T &&)一个(部件)函数模板的)template< typename T > f(T &&);,然后T &&是所谓的转发参考,并且T要么是U,或U &对于一些CV-合格类型U.但是对于成员函数的cv-ref-qualifiers,没有这样的规则.在struct S { void f() && { ; } };一个S::f()总是rvalue-reference限定符.

在通用代码中volatile,如果所有这些函数通常都做同样的事情,那么避免定义4(甚至8,如果我们也考虑限定符)某些成员函数的重载将是非常有用的.

中出现的这种方式的另一个问题,这是不可能的,以限定一个有效的CV-REF-限定符*this在特定的意义.以下代码不允许确定成员函数的ref限定符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;
}
Run Code Online (Sandbox Code Playgroud)

但如果有上述语法,那将是非常好的.即decltype((*this))表示精确的cv-ref限定类型*this.在我看来,将这样的语法引入即将推出的C++标准版本并不是一个突破性的变化.但是&&作为转发cv-ref-qualifier是(并且它看起来像委员会的遗漏(即核心语言工作组)).

另一序列可以表示两个成员函数CV-REF-限定符CV-REF-合格的类型*this到其体:auto &&,decltype(&&)

是否有关于此问题的提案,准备在C++ 17中使用

Rum*_*rak 1

是的,有这样的建议。

背景:

由于我们已经在模板函数中转发了引用,因此您可以简单地将成员函数转换为模板友元函数(并通过保护它enable_if不被与 以外的任何其他类一起使用F(如果需要)。

现在,也许您真的非常想将函数用作成员函数,因为您真的非常喜欢这种语法。

建议:

查找统一调用语法建议,例如:n4174

如果接受类似的内容,您将能够使用自由函数,例如第一个参数的成员函数。这将涵盖您在第一条评论中链接的示例代码。诚然,它不会涵盖 operator(),但我认为与编写 8 个重载相比,这只是一个小麻烦:-)