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

时间:2015-09-30 06:39:06

标签: c++ c++11 member-functions c++17 ref-qualifier

如果(成员)功能模板f(T &)没有其他重载(例如,f(volatile T &&)template< typename T > f(T &&);),那么T &&就是所谓的对于某些 cv-qualified 类型T,转发参考UU &U。但是对于成员函数的 cv-ref-qualifiers ,没有这样的规则。在struct S { void f() && { ; } };中,S::f()始终具有rvalue-reference限定符。

在通用代码中,如果所有这些函数都执行相同的操作,则避免定义4(甚至8,如果我们也考虑volatile限定符)某些成员函数的重载将是非常有用的。

以这种方式出现的另一个问题是,在特定意义上定义*this的有效 cv-ref-qualifier 是不可能的。以下代码不允许用户确定成员函数operator () ref-qualifier &&的{​​{1}}。

&

但如果有上述语法,那将是非常好的。即#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 类型。在我看来,将这种语法引入到 C ++ 标准的版本中并不是一个突破性的变化。但是*this作为转发cv-ref-qualifier (它看起来像是委员会的遗漏(即核心语言工作组))。

另一个序列可以将成员函数 cv-ref-qualifier cv-ref-qualified 类型&&表示到其正文中:{ {1}},*this等。

是否有针对此问题的提案,准备在 C ++ 17 中使用?

1 个答案:

答案 0 :(得分:1)

是的,有这样的建议。

<强>背景

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

现在,也许你想要你真的,真的想把你的函数用作成员函数,因为你真的非常喜欢那种语法。

提案:

查找统一呼叫语法提案,例如:n4174

如果接受了类似的东西,你就可以使用第一个参数的成员函数之类的自由函数。这将涵盖您在第一条评论中链接的示例代码。不可否认,它不会涵盖operator(),但我认为与编写8个重载相比,这是一个小麻烦: - )