减少" const char *"和" const std :: string&"参数

时间:2014-04-30 11:17:29

标签: c++ overloading

问题

我发现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!

要求

所以我认为有一个更好的选择:

  1. 不需要写重载。
  2. 在功能签名上不是那么难看。
  3. 不会影响性能。
  4. 不会涉及在函数内部编写(太多)额外代码。
  5. 可能的替代方案

    我认为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;
    }
    

    类似的课程是否已经存在?还是有更好的选择?

    编辑:如果有许多类似字符串的参数,问题会很快升级。在我的例子中只有一个,但它们可以很多。

2 个答案:

答案 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次调用可能有性能影响,而只是碰撞整数便宜)。