如何从标准::string_view正确创建标准::字符串?

How to correctly create std::string from a std::string_view?

本文关键字:标准 创建 字符串 string view      更新时间:2023-10-16

我有一个类:

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'tor 取范围。std::string有一个构造函数,它以std::string_view操作,列表中的数字为 10。其效果是

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

隐式地将 t 转换为字符串视图 sv 好像按std::basic_string_view<CharT, Traits> sv = t;,然后用sv的内容初始化字符串,好像按basic_string(sv.data(), sv.size(), alloc)。仅当std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>>为真且std::is_convertible_v<const T&, const CharT*>为假时,此重载才参与重载解析。

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

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

如果您在C++中有一些要转换为字符串格式的string_view(例如,您可以在执行所有分析后返回到函数(,则可以通过执行以下操作进行更改:

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

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

string s;
string_view sv = string_view(s);

请注意,子字符串和各种其他操作可以像对字符串一样对string_view执行。

第一种方法正确吗?

这是因为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实现如何,此方法都是安全的。