【问题标题】:How to correctly create std::string from a std::string_view?如何从 std::string_view 正确创建 std::string?
【发布时间】:2020-04-12 21:59:57
【问题描述】:

我有一堂课:

class Symbol_t {
public:
   Symbol_t( const char* rawName ) {
      memcpy( m_V, rawName, 6 * sizeof( char ) );
   };

   string_view strVw() const {
      return string_view( m_V, 6 );
   };

private:
   char m_V[6];

}; // class Symbol_t

还有一个我无法修改的 lib-func:

extern bool loadData( const string& strSymbol );

如果有局部变量:

Symbol_t   symbol( "123456" );

当我需要调用loadData时,我不敢这样做:

loadData( string( symbol.strVw().begin(), symbol.strVw().end() ) );

我必须这样做:

string_view svwSym = symbol.strVw();
loadData( string( svw.begin(), svw.end() ) );

我的问题: 第一种方法正确吗?还是我必须使用第二个?

因为我认为在方法 1 中,我传递给 std::string 的构造函数的迭代器是两个不同的 string_vew 对象,理论上结果是未定义的,即使我们会得到几乎所有的预期结果C++ 编译器。

任何提示将不胜感激!谢谢。

【问题讨论】:

    标签: c++ string iterator c++17 string-view


    【解决方案1】:

    第一种方法正确吗?

    因为strVw 返回相同的string_views:它们都指向相同的m_V 并且具有相同的大小。

    这里的正确性取决于strVw是如何实现的。

    或者我必须使用第二个?

    我会创建一个转换函数:

    inline std::string as_string(std::string_view v) { 
        return {v.data(), v.size()}; 
    }
    

    然后使用它:

    loadData(as_string(symbol.strVw()));
    

    无论strVw 实现如何,此方法都是安全的。

    【讨论】:

      【解决方案2】:

      没有必要使用 c'tor 获取范围。 std::string 有一个构造函数,根据列表中的std::string_viewnumber 10 进行操作。其中的效果是

      template < class T >
      explicit basic_string( const T& t, const Allocator& alloc = Allocator() ); 
      

      将 t 隐式转换为字符串视图 sv,就像 std::basic_string_view&lt;CharT, Traits&gt; sv = t; 一样,然后使用 sv 的内容初始化字符串,就像 basic_string(sv.data(), sv.size(), alloc) 一样。此重载仅在std::is_convertible_v&lt;const T&amp;, std::basic_string_view&lt;CharT, Traits&gt;&gt; 为真且std::is_convertible_v&lt;const T&amp;, const CharT*&gt; 为假时参与重载解析。

      由于std::string_view 本身的两个条件都成立,我们可以简单地编写对loadData 的调用:

      loadData( std::string( symbol.strVw() ) );
      

      【讨论】:

        【解决方案3】:

        如果您想将 C++ 中的一些 string_view 转换为字符串格式(例如,您可以在完成所有分析后返回到函数),您可以通过以下方式进行更改:

        string_view sv;
        string s = {sv.begin(), sv.end()};
        

        反过来,要从字符串中获取 string_view(以便获取指向该字符串的指针),您可以这样做:

        string s;
        string_view sv = string_view(s);
        

        注意 substring 和其他各种操作可以在 string_view 上执行,就像在 string 上一样。

        【讨论】:

          猜你喜欢
          • 2021-10-27
          • 2021-12-10
          • 2021-08-11
          • 1970-01-01
          • 1970-01-01
          • 2017-02-28
          • 2013-09-12
          • 2020-05-01
          • 2021-08-13
          相关资源
          最近更新 更多