减少"const char*"和"const std::string&"参数的过载
Reducing overloading on both "const char*" and "const std::string&" arguments
问题
我发现std::basic_string
的c_str
成员函数很难看,但同时我不希望创建大量临时std::basic_string
的性能受到影响。
示例
例如,给定以下函数签名:
void foo(const char* s);
void bar(const std::string& s);
显式调用c_str
如果我有一个std::string
,我必须在调用站点显式调用c_str
成员函数才能调用foo
,这有点难看。
std::string s = "...";
foo(s.c_str()); // Yuck! Ugly!
创建临时性
但是,如果我已经有了const char*
,编译器需要创建一个临时std::string
来调用bar
,可能会影响性能。
const char* s = "...";
bar(s); // Yuck! Potentially a performance hit!
过载
另一方面,我可以为两者提供重载,并将结果从一个转发到另一个,但由于懒惰,我不想编写超出需要的代码。
void baz(const char* s);
// Yuck! Carpal tunnel syndrome imminent.
inline void baz(const std::string& s)
{
baz(s.c_str());
}
要求
所以我认为有一个更好的选择:
- 不需要写入重载
- 函数签名不是很难看吗
- 不会影响演出
- 不会涉及在函数中编写(太多(额外的代码
可能的替代方案
我原以为boost::string_ref
在这方面会对我有所帮助,但它缺乏一种转换为const char*
的廉价方法。
解决方案
所以我想创建一个新的类来帮助我实现这一点,就像这样:
class c_str
{
public:
c_str(const char* s)
: s(s)
{
}
c_str(const std::string& s)
: s(s.c_str())
{
}
operator const char*() const
{
return s;
}
private:
const char* s;
};
void qux(const c_str& s)
{
std::string s1 = s;
const char* s2 = s;
std::cout << s;
}
用法
foo("s1");
const char* s2 = "s2";
foo(s2);
const std::string s3 = "s3";
foo(s3);
foo(std::string("s4"));
类似的类是否已经存在?或者还有更好的选择吗?
编辑:如果有许多类似字符串的参数,问题会很快升级。在我的例子中只有一个,但可以有很多。
不要低估现代编译器的威力。在考虑优化这样的代码之前,一定要先进行评测。
IMO,在编写优化代码之前,最好先编写干净、可维护和安全的代码,尽量比库更"智能"。
如果您必须对字符串(char*或std::string(操作进行优化,因为您的应用程序的目标是处理字符串(大型字符串数据集(,那么您可能需要为您的特定用途找到其他类型的容器(和/或字符串池…(。
实际上,string_ref
正是为了解决这个问题。
char const*
的问题是没有嵌入长度;C字符串在第一次出现NUL字符(