C++ 进阶汇总 [持续更新-建议收藏]

2.using 类内函数指针重命名 [相同类型不同函数,放置到 std::map 中会有用,减少代码量]

#include <iostream>

class c{
public:
        using pfunc_type = void(c::*)();
        pfunc_type pfunc = nullptr;
        c(){ pfunc = &c::up;}
        inline void call(){ (this->*pfunc)(); }
private:
        int num                  = 0;
        void up(){
                ++num;
                std::cout << num << std::endl;
        }
};

int main(){
        c  *C = new c;
        C->call();
        delete C;
}

3.指针引用

#include <iostream>
int main(){
        int a = 3;
        
        /* 指针引用 */
        int * const &p = &a;
        *p = 4;
        std::cout << a << std::endl;
        
        /* 原始引用 */
        int &theA = *p;
        theA = 5;
        std::cout << a << std::endl;
}

4.tuple使用

#include <iostream>
#include <tuple>
#include <functional>
#include <string>

int main() {

        /* 声明时赋值 */
        std::tuple<std::string, std::function<void()>> tp("i++", [](){
                static int i = 0;
                std::cout << i++ << std::endl;
        } );

        std::cout << "call " << std::get<0>(tp) << std::endl;
        std::get<1>(tp)();
        /* 先声明,后赋值 */
        std::tuple<float, std::string> id2name;
        id2name = make_tuple(1.5, std::string("gulou"));
        std::cout << "id :" << std::get<0>(id2name) << " name :" << std::get<1>(id2name) << std::endl;
}

5.读取文件到字符串 [遇到 空格/回车 结束]

#include <iostream>
#include <fstream>
#include <string>

inline std::string readUrl( std::string fName="input.txt", std::string result="" ) { std::ifstream os; return os.open(fName), os >> result, os.close(), result; }

int main()
{
        std::cout << readUrl();
}

6.call_once 控制调用一次

#include <iostream>
#include <mutex>

/* compile : g++ call_once.cpp -std=c++11 -pthread */
int main(){
    std::once_flag flag; /* 如果你的函数操作不会产生异常,那么可以使用std::call_once,使得代码更加的安全简洁易读。 */
    unsigned int MAX = 50;

    std::call_once(flag, [&MAX ]() { MAX = (MAX == 50) ? (MAX + 2950) : MAX ; } );
    std::call_once(flag, [&MAX ]() { MAX = (MAX == 50) ? (MAX + 2950) : MAX ; } );

    std::cout << MAX << std::endl; /* output :3000 */
}

7.algorithm 之 find_if 、swap

#include <iostream>     /* std::cout */
#include <algorithm>    /* std::find_if */
#include <vector>       /* std::vector */

/* compile : g++ find_if.cpp -std=c++11 */
int main () {
	std::vector<int> vec_i;
	
	vec_i.push_back(10);
	vec_i.push_back(55);
	vec_i.push_back(25);
	
	/*      Returns an iterator to the first element in the range [first,last) for which pred returns true.
	        If no such element is found, the function returns last. */
	auto it = std::find_if (vec_i.begin(), vec_i.end(), [](int &i) { return (i%2) == 1; });
	if ( it != vec_i.end() ) {
	        std::cout << "The first odd value is " << *it << std::endl;
	}
	
	std::swap(vec_i[1], vec_i[2]); /* Exchanges the values of a and b. parameters all reference, impl by std::move */
	
	it = std::find_if (vec_i.begin(), vec_i.end(), [](int &i) { return (i%2) == 1; });
	if ( it != vec_i.end() ) {
	        std::cout << "The first odd value is " << *it << std::endl;
	}
	return 0;
}


8.unique_ptr 示例

    std::unique_ptr<AVFrame, void(*)(AVFrame*) > unique_p(av_frame_alloc(), [](AVFrame *ptr){
        av_frame_free(&ptr);
    });

9.运行时计算 【constexpr 】

#include <iostream>
#include <string>

enum class languageType:int {
    CH,
    EN,
    JAP,
};

static languageType lan = languageType::EN;

constexpr const char* languageName ( const languageType lan) {
        return languageType::CH == lan ? "中文": \
               languageType::EN == lan ? "English" : \
               /*     JAP     */         "日本語";
}

int main(){
  std::cout << languageName (lan) << std::endl;
  return 0;
}
---

10.字符串格式化 【string format 】

std::string StringFormat(const char* fmt, ...) {

	char buffer[kMaxSize];
	
	va_list args;
	va_start(args, fmt);
	int result = vsnprintf(buffer, kMaxSize, fmt, args);
	va_end(args);
	
	if ( result < 0) { /* error */
	      std::cout << "String Format Convert Error : " << kMaxSize << " " << result << std::endl;
	} else if ( result > kMaxSize ) { /* warning */
	      std::cout << "String Format Convert Warning : truncated string" << std::endl;
	}
	
	return std::string(buffer);
}
/* usage:
	std::cout << StringFormat("hello %s","world!") << std::endl;
*/

11.字符串查找最后一个对应字符后的字符串

#include<bits/stdc++.h>

int main(){
        std::string s(R"(https://editor.csdn.net/md/?articleId=126165427)");
        int ret = s.find_last_of('/');
        if (ret != std::string::npos) {
                s = s.substr(ret+1, 999);;
                std::cout << s << std::endl;
        } else {
                std::cout << "error" << std::endl;
        }
}
/*  result:
[root@jn string]# ./a.out
?articleId=126165427
[root@jn string]#*/

12.基于C++11的毫秒计时器类,精度到0.001ms,开箱即用

#include <iostream>
#include <chrono>
#include <thread>

class jnTimer {
public: /* return milliseconds escaped, Precision to 0.001 ms*/
    jnTimer(){ update(); }
    inline void update() { begin = HrClock::now(); }
    inline double diff() { return std::chrono::duration_cast<MicroSeconds>(HrClock::now() - begin).count() / 1e3; }

private:
    using HrClock      = std::chrono::high_resolution_clock;
    using MicroSeconds = std::chrono::microseconds;

    HrClock::time_point  begin{ MicroSeconds::zero() };
};

/* compile: g++ -std=c++11 timer.cpp */
int main()
{
        jnTimer timer; /* timer.update(); */
        std::this_thread::sleep_for( std::chrono::milliseconds( 300 ) );/* do your work */
        std::cout << "diff:" << timer.diff() << std::endl;

        return 0;
}

13.三分钟读完《Essential C++》
https://blog.csdn.net/weixin_44328568/article/details/131720185


14.计算字节为对应单位的大小[human-readable]

#include <stdint.h>
#include <cstdlib>
#include <cstdio>
std::string bytesToSize(uint64_t bytes)
{
    static const char* suffixes[] = {"B", "KB", "MB", "GB", "TB"};
    int i = 0;
    double dblBytes = bytes;
    while (dblBytes >= 1024 && i < sizeof(suffixes) / sizeof(suffixes[0]) - 1) {
        dblBytes /= 1024;
        i++;
    }
    char buffer[32];
    snprintf(buffer, sizeof(buffer), "%.2f %s", dblBytes, suffixes[i]);
    return std::string(buffer);
}

15.enum与字符串在固定(不修改)数据上的关联操作[代替std::map会更高效]

#include <iostream>
#include <string>

enum Fruit {
    APPLE,
    BANANA,
    CHERRY,
    COUNT /* COUNT 用于获取 enum 的项数,始终放在最后 */
};

const std::string FruitNames[COUNT] = {
    "Apple",
    "Banana",
    "Cherry"
};

int main() {
    Fruit fruit = BANANA;

    std::cout << "Selected fruit: " << FruitNames[fruit] << std::endl;

    return 0;
}

posted on 2023-09-15 16:34  杜jn  阅读(63)  评论(0编辑  收藏  举报