转发成员函数的cv-ref-qualifier
Forwarding cv-ref-qualifier for member functions
如果(成员)函数模板template< typename T > f(T &&);
没有其他重载(如f(T &)
或f(volatile T &&)
),则T &&
为所谓的转发引用, T
为U
或U &
,对于某些cv合格的类型U
。但是对于成员函数的cv-ref-qualifiers没有这样的规则。在struct S { void f() && { ; } };
中,S::f()
总是有右值-引用限定符。
在泛型代码中,避免某些成员函数的4(甚至8,如果我们还考虑volatile
限定符)重载的定义是非常有用的,在所有成员函数都做一般相同的事情的情况下。
*this
的有效cv-ref-限定符。下面的代码不允许确定成员函数operator ()
的ref-限定符是否为&
的&&
。
#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))
表示*this
的确切cv-ref-qualified类型。在我看来,在 c++ 标准的下一个版本中引入这样的语法并不是一个突破性的变化。但是&&
作为转发cv-ref-qualifier是(并且它看起来像是委员会(即核心语言工作组)的遗漏)。
另一个序列可以同时表示*this
的成员函数cv-ref-qualifier和cv-ref-qualified类型:auto &&
、decltype(&&)
等。
是否有关于这个问题的建议,准备在 c++ 17使用?
是的,有这样的建议。
背景:因为我们已经在模板函数中有了转发引用,你可以简单地把你的成员函数变成模板友元函数(如果需要的话,可以通过enable_if
保护它不被F
以外的任何其他类使用)。
现在,也许你非常非常想将你的函数用作成员函数,因为你非常非常喜欢这种语法。
建议:
查找统一调用语法建议,例如:n4174
如果接受这样的内容,则可以使用自由函数,例如第一个实参的成员函数。这将涵盖您在第一个注释中链接的示例代码。不可否认,它不会涵盖operator(),但我认为与编写8个重载相比,这是一个小麻烦:-)
- 对RValue对象调用的LValue ref限定成员函数
- 将Ref对象作为类成员
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 概念中的cv限定符需要表达式参数列表
- 为什么我的 std::ref 无法按预期工作?
- 将CHW格式的浮点向量转换为cv::Mat
- 错误的cv::face FacemarkLBF实例化
- 如何将 Eigen::Ref 与 pybind11 一起使用?
- 如何检查给定的参数是否为 cv::noArray()?
- 开放 CV 中的动态内存分配,用于视频处理
- 如何@ref同一方法的不同变体?
- 如何在 opencv 中使用 cv::VideoCapture::waitAny()
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 错误:未定义对cv::cudacodec::createVideoReader的引用
- 如何在C 中检查确切的类型信息(具有CV-REF-POIRT特征)
- 嵌套模板参数以及函数参数的 cv 和 ref- 限定符
- Typedef 用于指向 cv 和/或 ref 限定成员函数的指针
- “auto”的ref和cv剥离属性
- 转发成员函数的cv-ref-qualifier
- 为什么lambda去掉cv和ref