转发成员函数的cv-ref-qualifier [英] Forwarding cv-ref-qualifier for member functions

查看:302
本文介绍了转发成员函数的cv-ref-qualifier的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果没有其他重载(例如 f(T&) f(volatile T&& c $ c>)(<成员)函数模板 template<类型名T> f(T& amp;); ,则 T&&& 是所谓的转发引用 T U U& 一些 cv限定类型 U 。但是对于成员函数的 cv-ref-qualifiers ,没有这样的规则。在 struct S {void f()&& {; }}; a S :: f()始终为rvalue-引用限定符。

If there are no another overloadings (say, f(T &) or f(volatile T &&)) of a (member) function template template< typename T > f(T &&);, then T && is so-called forwarding reference, and T is either U, or U & for some cv-qualified type U. But for cv-ref-qualifiers of member functions there is no such a rule. In struct S { void f() && { ; } }; a S::f() has always rvalue-reference qualifier.

在通用代码中,避免定义4(甚至8,如果我们也考虑 volatile 限定符)重载某些成员函数是非常有用的,如果case

In generic code it would be very useful to avoid a definition of 4 (or even 8, if we also consider volatile qualifier) overloadings of some member function, in cases if all of them doing generally the same thing.

以这种方式出现的另一个问题是,不可能定义有效的 cv-ref-qualifier > * this 。以下代码不允许确定成员函数 operator() ref-qualifier 是& 和

Another problem that arises in this way, it is impossibility to define an effective cv-ref-qualifier of *this in a particular sense. Following code not allows one to determine whether the ref-qualifier of a member function operator () is && of &.

#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 是(看起来像是省略了委员会)。

But it would be very nice, if there was above syntax. I.e. decltype((*this)) denote exact cv-ref-qualified type of *this. It would not be a breaking-change to introduce such a syntax into coming version of the C++ standard at my mind. But && as forwarding cv-ref-qualifier is (and it looks like an omission of the committee (namely, core language working group)).

另一个序列可以表示成员函数 cv-ref-qualifier cv-ref-qualified 类型 * this 加入其正文: auto&&& decltype (&&)等。

Another sequence is possible to denote both the member function cv-ref-qualifier and cv-ref-qualified type of *this into its body: auto &&, decltype(&&) etc.

有关于此问题的提案,准备在 C ++ 17

Is there a proposal regarding this issue, prepared for use in C++17?

推荐答案

是的,有这样的建议。

背景:

由于我们已经在模板函数中拥有转发引用,因此您可以简单地将成员函数转换为模板朋友函数如果需要,通过 enable_if 与任何其他类别 F 一起使用。

Since we already have forwarding references in template functions, you could simply turn your member function into a template friend function (and protect it via enable_if from being used with any other class than F, if required).

现在,也许你想要你的真正的,真的想使用你的函数作为一个成员函数,因为你真的,真的很喜欢那种语法更好。

Now, maybe you want your really, really want to use your function as a member function, because you really, really like that syntax so much better.

提案:

查看统一通话语法建议,例如: n4174

Look up unified call syntax proposals, for instance: n4174

如果有东西像接受它,你将能够使用自由函数,如第一个参数的成员函数。这将涵盖您在第一个评论中链接的示例代码。当然,它不会覆盖operator(),但我认为与写8个重载相比较小的麻烦: - )

If something like that is accepted, it you will be able to use free functions like member functions of the first argument. This would cover the example code you linked in your first comment. Admittedly, it would not cover operator(), but I consider that a minor nuisance compared to writing 8 overloads :-)

这篇关于转发成员函数的cv-ref-qualifier的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆