记录一下学习优秀代码的一些技巧

  • string_view c++17引入的特性,避免 const char* 与string相互赋值的时候string的深拷贝
  • strcspn 返回字符串开头连续不含字符串reject的字符数目 strspn返回字符串开头连续包含字符串accept的字符个数
  • split精彩实现
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
template <typename F>
inline void split(const F& function, const char* cstr, const char delim = ' ') {
do {
auto start = cstr;
while (*cstr != delim && *cstr != '\0') ++cstr;
function(start, cstr - start);
} while (*cstr++ != '\0');
}

template <typename F>
inline void split(const F& function, const ::std::string& str, const char delim = ' ') {
split(function, str.c_str(), delim);
}

// VS == std::vector<std::string>
template <typename VS>
inline void split(VS& tokens, const char* cstr, const char delim = ' ') {
size_t num = 0;
split([&tokens, &num] (const char* begin, size_t length) {
if (num < tokens.size()) {
tokens[num].assign(begin, length);  //这里进行了tokens的重用,避免clear重新分配内存
} else {
tokens.emplace_back(begin, length); //右值构造,一次赋值
}
++num;
}, cstr, delim);
tokens.resize(num);
}
  • 使用likely(x)优化条件语句,当大部分情况会落入该分支的时候使用,可以避免大部分汇编语句的跳转,优化执行性能。解释
1
2
#define unlikely(x) __buildin_expect((x), 0)
#define likely(x) __buildin_expect((x), 1)
  • enum可以用于模板。感觉很优雅
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
enum class Encoding {
GB18030 = 1,
UTF8 = 3,
GBK = 13,
};
template <Encoding T, Encoding F, IconvOnError O = IconvOnError::ABORT>
inline int32_t iconv_convert(::std::string& output, ::std::string_view input) noexcept {
thread_local IconvConverter<T, F, O> converter; //thread_local c++11关键词,线程生命周期的对象
return converter.convert(output, input);
}
//使用
iconv_convert<Encoding::GB18030, Encoding::UTF8>(output, input);
  • std::decay可以将T的右值,左值,引用等退化成T
1
2
3
4
template <typename T, typename U>
struct decay_equiv : 
std::is_same<typename std::decay<T>::type, U>::type 
{};