一、显示指定this
c++23中的Deducing This,可以理解为显示的指定this.在Python语言中,其类的成员函数中第一个参数一般默认为self,用来操作类的成员,类似下面的代码:
class Demo:
def __init__(self,name,age):
self.name = name
self.__age = age
def show(self):
print(self.name,self.__age)
d = Demo("alice",10)
d.show()
而在c++中一般来说,针对非静态成员,默认在其中有一个this指针,换句话说,这个this是隐式的。用this指针传递的一定是一个引用,这就对c++11后的右值引用和完美转发其实有了隐形的限制。同时,一些view type其实值传递更有优势。所以c++23中提出了类似于上述Python的方式,也就是将第一个参数加this则形成类似self的实现方式:
struct A_old {
void test() &;
void test() const&;
void ok() &&;
};
struct A_explicit {
void test(this X& self);
void test(this X const& self);
void ok(this X&&);
};
所以一直说语言未来的发展趋势大方向一定是趋同的,虽然可能实现的手段和机制各有千秋,这个Deducing This又是一个例子啊。
二、应用及例程
这么做有什么好处或者应用在哪些方面呢,主要有三个:
1、多个重载函数的模板化操作
struct A
{
void bar() & { /* ... */ }
void bar() && { /* ... */ }
void bar() const & { /* ... */ }
void bar() const && { /* ... * / }
}
//C++23显示this
struct A {
template <typename Self>
void bar(this Self&& self);
};
这样重载越是多,优势就越明显。
2、值类型的处理
class string_view
{
public:
constexpr const char* begin(this string_view self)
{
return self.data;
}
constexpr const char* end(this string_view self)
{
return self.data + self.size;
}
private:
const char* data;
std::size_t size;
};
3、lambda表达式的递归应用
看一个应用:
int main()
{
auto Fn = [](this auto self, int n) {
if (n <= 1) return 1;
return n * self(n - 1);
};
auto r = Fn(3);
}
这种类型如果在以前就得增加一个std::function来处理类似的动作,而使用self这种情况就方便简化了不少。
- 代码参考自标准草案或相关网站
三、总结
其实现在写c++23为时尚早,剧透虽然会引起大家一些兴趣,但如果最终结果与实际标准落地有区别,等于是变相走了些弯路。毕竟在前面又不是没有过类似的例子。不过还是那句话,多学一点没有坏处,正所谓知其所以然,才会在标准落地后能够更快的了解和应用这些新功能。当然如果废弃了就没办法了。
大家试为观之。