我发现c_str
的{{1}}成员函数很难看,但与此同时我不希望创建大量临时std::basic_string
的性能受到影响。
例如,给定这些功能签名:
std::basic_string
明确调用c_str
如果我有void foo(const char* s);
void bar(const std::string& s);
,我必须在呼叫网站明确调用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!
所以我认为有一个更好的选择:
我认为boost::string_ref
会对我有帮助,但缺少一种廉价的方式转换为void baz(const char* s);
// Yuck! Carpal tunnel syndrome imminent.
inline void baz(const std::string& s)
{
baz(s.c_str());
}
。
所以我想创建一个可以帮助我实现这一目标的新类,就像这样:
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;
}
类似的课程是否已经存在?还是有更好的选择?
编辑:如果有许多类似字符串的参数,问题会很快升级。在我的例子中只有一个,但它们可以很多。
答案 0 :(得分:2)
不要低估现代编译器的强大功能。 并且在考虑优化代码之前总是进行分析。
IMO,最好在编写优化代码之前编写干净,可维护且安全的代码,方法是尝试更多&#34; intelligenter&#34;比图书馆。
如果你必须要对opt(char *或std :: string)操作进行优化,因为它是你的应用程序使用字符串(大字符串数据集)的目标,也许你需要找到其他类型容器(和/或字符串池,...)的特定用途。
答案 1 :(得分:0)
实际上,string_ref
正好可以解决这个问题。
char const*
的问题是没有嵌入长度;一个C字符串在第一次出现NUL字符(\0
)时结束,这意味着每当使用std::string::c_str
时,字符串中嵌入的NUL字符都有可能意味着生成的C字符串是仅部分由客户使用。
另一方面,string_ref
嵌入了char const*
和显式长度,因此适用于包含NUL的整个字符集。因此,如果性能很重要,解决方案是使用string_ref
。
当然,性能是否重要(在此呼叫站点)或者您是否真正获得char const*
首先是另一个故事。通常,在C ++中,char const*
是一个奇怪的东西(你可以使用std::string const
常量)并且string_ref
唯一真正感兴趣的地方是解析(因为很多substr
次调用可能有性能影响,而只是碰撞整数便宜)。