工程常用C++用法

Including .cpp files
thrift 的required、optional探究

命令行参数:

#include <gflags/gflags.h>
DEFINE_string(conf_file, "conf/testing.conf", "config file");
gflags::ParseCommandLineFlags(&argc, (char***)&argv, true);
conf::init(FLAGS_conf_file);
# 捕获异常
try {
	throw std::runtime_error("input doc error");
} catch (std::exception& ex) {
    LOGF_ERROR("Exception thrown! reason: %s", ex.what());
    return -1;
} catch (...) {
    LOGF_ERROR("Exception thrown! reason unknown");
    return -1;
}

move用法:
C++11右值引用和std::move语句实例解析
std::move()实际应用分析
请勿使用return std::move(obj)返回右值引用

make share用法:
shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting),比如我们把只能指针赋值给另外一个对象,那么对象多了一个智能指针指向它,所以这个时候引用计数会增加一个,我们可以用shared_ptr.use_count()函数查看这个智能指针的引用计数,一旦最后一个这样的指针被销毁.
Difference in make_shared and normal shared_ptr in C++
智能指针之shared_ptr基本概述

#include <cpputil/program/conf.h>
extern std::shared_ptr<cpputil::program::Conf> conf;
conf = std::make_shared<cpputil::program::Conf>(filename);


auto servable = std::shared_ptr<Servable>(new EmbeddingServable(FLAGS_model));


int a = new int(100);
std::shared_ptr ptr(a);

std::shared_ptr<int> ptr1 = std::make_shared<int>(15);

std::shared_ptr<int> ptr2(ptr1);
//std::shared_ptr<int> ptr2 = ptr1;这样赋值是错误的,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr2(ptr1);
数据格式转换:
#include <boost/lexical_cast.hpp>
boost::lexical_cast<int>(value);
try {
    return boost::lexical_cast<double>(vs);
} catch (boost::bad_lexical_cast) { 
    return default_val;
}

# 字符串拆分
#include <boost/algorithm/string.hpp>
boost::algorithm::split(str_gpus, FLAGS_gpus, boost::algorithm::is_any_of(","));
路径:

::boost::filesystem::path model_root(conf::get_str("model_root"));
::boost::filesystem::path vocab2id_path8(model_root);
vocab2id_path8.append("s1.3.txt", boost::filesystem::path::codecvt());

std::vector<std::pair<std::string, std::string>> pb_path_vec{
        std::make_pair("s1.3", vocab2id_path8.string()),
};
无锁队列:

#include <concurrentqueue/blockingconcurrentqueue.h>
query_queue_ = std::make_shared<moodycamel::BlockingConcurrentQueue<Item>>(10240);

vector 用法:


std::vector<std::thread> threads_seq2seq;
for (int i=0;i<num_threads_seq2seq;++i) {
    threads_seq2seq.emplace_back(std::thread([]{Singleton<Seq2seqServing>::instance().run();}));
}

(1): vector<int> ilist1;

    默认初始化,vector为空, size为0,表明容器中没有元素,而且 capacity 也返回 0,意味着还没有分配内存空间。这种初始化方式适用于元素个数未知,需要在程序中动态添加的情况。

(2): vector<int> ilist2(ilist);

vector<int> ilist2  = ilist; 

两种方式等价 ,ilist2 初始化为ilist 的拷贝,ilist必须与ilist2 类型相同,也就是同为int的vector类型,ilist2将具有和ilist相同的容量和元素

(3): vector<int> ilist = {1,2,3.0,4,5,6,7};

 vector<int> ilist {1,2,3.0,4,5,6,7};

ilist 初始化为列表中元素的拷贝,列表中元素必须与ilist的元素类型相容,本例中必须是与整数类型相容的类型,整形会直接拷贝,其他类型会进行类型转换。

(4): vector<int> ilist3(ilist.begin()+2,ilist.end()-1);

ilist3初始化为两个迭代器指定范围中元素的拷贝,范围中的元素类型必须与ilist3 的元素类型相容,在本例中ilist3被初始化为{3,4,5,6}。注意:由于只要求范围中的元素类型与待初始化的容器的元素类型相容,因此迭代器来自不同的容器是可能的,例如,用一个double的list的范围来初始化ilist3是可行的。另外由于构造函数只是读取范围中的元素进行拷贝,因此使用普通迭代器还是const迭代器来指出范围并没有区别。这种初始化方法特别适合于获取一个序列的子序列。

(5): vector<int> ilist4(7);

默认值初始化,ilist4中将包含7个元素,每个元素进行缺省的值初始化,对于int,也就是被赋值为0,因此ilist4被初始化为包含7个0。当程序运行初期元素大致数量可预知,而元素的值需要动态获取的时候,可采用这种初始化方式。

(6):vector<int> ilist5(7,3);

指定值初始化,ilist5被初始化为包含7个值为3的int
std::vector<GroupBuilder> groups_
groups_.emplace_back(engine, group, vocab);

匿名函数

auto fill_one_field = [](FieldInfo& field_info) { do something }

Lambda 表达式本质上与函数声明非常类似。Lambda 表达式具体形式如下:

[capture](parameters)->return-type{body}
例如:

[](int x, int y){ return x < y ; }
如果没有返回值可以表示为:

[capture](parameters){body}
例如:

[]{ ++global_x; } 
在一个更为复杂的例子中,返回类型可以被明确的指定如下:

[](int x, int y) -> int { int z = x + y; return z + x; }

本例中,一个临时的参数 z 被创建用来存储中间结果。如同一般的函数,z 的值不会保留到下一次该不具名函数再次被调用时。

如果 lambda 函数没有传回值(例如 void),其返回类型可被完全忽略。

在Lambda表达式内可以访问当前作用域的变量,这是Lambda表达式的闭包(Closure)行为。 与JavaScript闭包不同,C++变量传递有传值和传引用的区别。可以通过前面的[]来指定:

[]      // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&]     // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=]     // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x]  // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。
另外有一点需要注意。对于[=]或[&]的形式,lambda 表达式可以直接使用 this 指针。但是,对于[]的形式,如果要使用 this 指针,必须显式传入:

[this]() { this->someFunc(); }();

指针的指针
1,2

int main(int argc, char* const argv[]) {
    gflags::ParseCommandLineFlags(&argc, (char***)&argv, true);
    return run_thrift_server(argc, (char**)argv);
}
class A
{
public:
	A() = default;//正确
	A(int _a) = default;//错误,构造函数需要没有默认参数
	int getA() = default;//错误,仅适用于类的特殊成员函数
}

class A
{
public:
    A();
    A(const A&) = delete;  // 声明拷贝构造函数为 deleted 函数
    A& operator = (const A &) = delete; // 声明拷贝赋值操作符为 deleted 函数
};

线程池:

#include <thread>
tp_ = std::make_shared<ThreadPool>();
tp_->start(static_cast<size_t>(conf::get_int("thread_pool_size", 16)));

omp编程:
OpenMP多线程linux下的使用,简单化

#inlcude <omp.h>
#pragma omp parallel for
#pragma omp for reduction(+: 变量)
#pragma omp critical//锁
{
}
#pragma omp parallel for private(x,y)//每个线程都独立拷贝x, y变量,互不干扰,如果不设默认是共享变量
#pragma omp parallel for schedule(static/dynamic/guided, k)//总工作量划分成n/k块,再多线程调度
#pragma omp parallel sections
{
    #pragma omp section//要保证几个section下的函数之间没有变量依赖
    .........
    #pragma omp section
    .........        
}
#pragma omp parallel
{
    .......();
    #pragma omp master/single //保证只有主线程/某个线程能访问下面的函数,区别是使用master没有barrier珊障,single的话先完成的线程等待没完成的线程
    {
    }
    .......
}

#pragma omp barrier/nowait //强制设置珊障/无需等待,如果后续函数对前面的多线程没有依赖,即可使用nowait
#pragma omp parallel for firstprivate(变量)/lastprivate(变量) //为每个多线程赋初值/出多线程回到主线程时赋值供主线程使用

std::future:
c++11多线程编程(八):std::future , std::promise和线程的返回值

std::vector<std::future<int>> rets;
rets = server_->batch_submit();
int ret = rets[i].get();

namespace:
header中使用
Using c++ typedef/using type alias
别再让C++头文件中出现“using namespace xxx;”

using Server = AAA::MultiThreadServer;
namespace whatevs
{
    enum Enum
    {
        FOO = 0,
        BAR,
        BLARGH,
        MEH,
        SIZE
    };
} // namespace whatevs


namespace on = whatevs;
#include "whatevsenum.hpp"
void do_something_with(on::Enum value)
{
    // do stuff
}
do_something_with(on::FOO);

或者 using namespace::whatevs::Enum;
Enum::FOO;
发布了557 篇原创文章 · 获赞 500 · 访问量 153万+

猜你喜欢

转载自blog.csdn.net/qq_16234613/article/details/94381957