如何正确地从std::string_view创建std::string?

37

我有一个类:

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

而且有一个我无法修改的库函数:

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() ) );

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

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

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

3个回答

50

不需要使用带范围的构造函数。 std::string 有一个基于 std::string_view 进行操作的构造函数,它在列表中排名第 10。其效果为

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

Implicitly converts t to a string view sv as if by std::basic_string_view<CharT, Traits> sv = t;, then initializes the string with the contents of sv, as if by basic_string(sv.data(), sv.size(), alloc). This overload only participates in overload resolution if std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>> is true and std::is_convertible_v<const T&, const CharT*> is false.

由于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);

请注意,与字符串相同,可以在"string_view"上执行子串和其他各种操作。

这难道不会完全复制字符串吗?string_view 的主要目的就是避免这种情况。 - Roflcopter4
@Roflcopter4,std::string 是一种值类型,拥有字符串的内存。实例化 std::string 需要进行完整复制,因为这正是使用该类型所要求的。 - Ad N

0
第一种方法正确吗?
是的,因为strVw返回相同的string_view:它们都指向相同的m_V并具有相同的大小。
这里的正确性取决于strVw的实现方式。
还是我必须使用第二个?
我会创建一个转换函数:
inline std::string as_string(std::string_view v) { 
    return {v.data(), v.size()}; 
}

并使用它:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接