title abseil C++ Tips
date: 2022-10-28 00:00
url: abseil_cpp_tips
学习abseil C++ Tips
Tip of the Week #1: string_view
当函数参数为(const) string时,常见的一般有3种方法,第三种方法可能不太常见。
// C Convention
void TakesCharStar(const char* s);
// Old Standard C++ convention
void TakesString(const std::string& s);
// string_view C++ conventions
void TakesStringView(absl::string_view s); // Abseil
void TakesStringView(std::string_view s); // C++17
前面两种方法只有当参数类型匹配时才比较方便,如果对void TakesCharStar(const char* s);函数传入std::string,需要调用c_str()函数。
void AlreadyHasString(const std::string& s) {
TakesCharStar(s.c_str()); // explicit conversion
}
如果是对函数void TakesString(const std::string& s);传入const char*,可以直接调用,但是实际上会触发std::string的拷贝构造函数,程序效率存在问题。
void AlreadyHasCharStar(const char* s) {
TakesString(s); // compiler will make a copy
}
What to Do ?
可以使用c++17中的sting_view或absl::string_view,string_view可以支持两种类型直接调用,虽然存在隐士类型转换,但不会拷贝整个数据,所以不存在O(n)的内存消耗。string_view只是记录了自身对应字符串的地址信息。当const char*作为参数时,隐含传入了strlen()作为string_view的构造参数。
void AlreadyHasString(const std::string& s) {
TakesStringView(s); // no explicit conversion; convenient!
}
void AlreadyHasCharStar(const char* s) {
TakesStringView(s); // no copy; efficient!
}
string_view详细教程参考:learn c++ string_view
尽量以const,enum,inline替换#define
宁可以编译器替换预处理器。
例如#define ASPECT_RATIO 1.653
符号ASPECT_RATIO从未被编译器看见,在预处理阶段已经完成替换,运行时错误时如果在代码中存在多个1.653将存在困惑。
解决办法是使用const double AspectRatio = 1.653,编译后进入符号表。
为了将常量的作用域限制于class内,你必须让它成为class的一个成员,为了确保此常量至多只有一份实例,你必须使用static.
#include <iostream>
using namespace std;
class GamePlayer {
private:
static const int NumTurns = 5;//常量声明式
int score[NumTurns];
};
int main(){
return 0;
}
如果需要取某个class专属常量的地址,必须使用如下方式:
#include <iostream>
using namespace std;
class GamePlayer {
public:
static const int NumTurns = 5;
int score[NumTurns];
};
const int GamePlayer::NumTurns;
int main(){
cout << GamePlayer::NumTurns << ",address NumTurns:"<<&GamePlayer::NumTurns;
return 0;
}