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)的内存消耗。当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!
}