C++20 auto &&写法

auto&&f

leetcode3823,

我的低级写法

class Solution {
public:
    string reverseByType(string s) {
        string ans;
        vector<char>alpha,spec;
        for(char c:s){
            if(islower(c)) alpha.push_back(c);
            else spec.push_back(c);
        }
        reverse(alpha.begin(),alpha.end());
        reverse(spec.begin(),spec.end());
        int aid = 0,sid = 0;
        for(char c:s){
            if(islower(c)) ans += alpha[aid++];
            else ans += spec[sid++];
        }
        return ans;
    }
};

灵神高级写法

class Solution {
    //这是C++20的写法,就是用来传递函数
    /*在早期的 C++ 中,如果想传入一个函数作为参数,
    代码会写得非常冗长(比如使用函数指针或 std::function)。
这里的 auto&& 是 C++20 的简写函数模板(Abbreviated Function Template) 
结合了 万能引用(Universal Reference)。
auto 告诉编译器:“不管传进来的是什么类型的函数(普通函数、Lambda 表达式),请你自动推导”。
&& 保证了无论传进来的是临时对象还是持久对象,都能以最高效的方式(避免拷贝)接收。
总结:这是一种现代 C++ 接收“回调函数”的最精简、最高效的写法。*/
    void reverse(string& s, auto&& f) {
        int i = 0;
        int j = s.size() - 1;
        while (i < j) {
            while (i < j && f(s[i])) {
                i++;
            }
            while (i < j && f(s[j])) {
                j--;
            }
            swap(s[i], s[j]);
            i++;
            j--;
        }
    }

public:
    string reverseByType(string s) {
        reverse(s, ::islower);
        reverse(s, [](char ch) { return !islower(ch); });
        return s;
    }
};

关于这个reverse这个函数有个要注意的地方

如果你自己定义了一个函数的话,假设叫yuan
你不可以直接写reverse(s,[](char h){return !yuan(h)})
就是涉及到了 C++ 中“成员函数”与“全局/标准库函数”的区别

简单来说:islower 不是你写的类 Solution 的一部分,它是 C++ 标准库提供的全局函数。
详细原因分析:

  1. islower 的身份
    islower 定义在 头文件中。它是一个全局函数(或者说位于 std 命名空间下的函数),它不需要依赖任何对象的状态。无论你在代码的哪个地方调用它,它的行为都是一样的,它不需要访问 this 指针。
  2. yuan 的身份
    yuan 是你定义的成员函数(Member Function)。
    成员函数默认有一个隐式的 this 参数,用来指向当前对象。
    当你调用 yuan(h) 时,编译器实际上是在执行 this->yuan(h)。
    Lambda 的限制:Lambda 表达式本质上是一个闭包类,它默认不会自动绑定当前的 this。如果你在 Lambda 内部直接写 yuan(h),编译器不知道这个 yuan 是从哪来的,因为它不是全局函数,必须通过 this 指针来寻找它。

就类型于下面这个代码

类似的代码

class Solution {
public:
   bool yuan(char s) {
    s = tolower(s);
    return s == 'a' || s == 'e' || s == 'i' || s == 'o' || s == 'u';
    }
    void reverse(string&s,auto&&f){
        int i=0,j=s.length()-1;
        while(i<j){
            while(i<j&&f(s[i]))i++;
            while(i<j&&f(s[j]))j--;
            swap(s[i],s[j]);
            i++,j--;
        }
    }
    string reverseVowels(string s) {
        reverse(s,[this](char h){return !yuan(h);});
        return s;
    }
};

但是,你如果把yuan函数放到类的外面就可以也不用this

关于这种函数的总结

只有当你调用当前类内部的成员(函数或变量)时,才需要显式捕获 this;调用全局函数或标准库函数时,不需要。

posted @ 2026-03-13 22:05  Time_q  阅读(2)  评论(0)    收藏  举报