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

2022-01-10 00:00:00 string iterator c++ c++17 string-view

我有一堂课:

类 Symbol_t {上市:Symbol_t( const char* rawName ) {memcpy(m_V, rawName, 6 * sizeof(char));};string_view strVw() const {返回字符串视图(m_V,6);};私人的:字符 m_V[6];};//类 Symbol_t

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

extern bool loadData( const string& strSymbol );

如果有局部变量:

Symbol_t 符号(123456");

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

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

我必须这样做:

string_view svwSym = symbol.strVw();加载数据(字符串(svw.begin(),svw.end()));

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

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

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

解决方案

没有必要使用c'tor取范围.std::string 有一个构造函数,根据 std::string_view、数字 10 在列表中.其中的效果是

<块引用>

模板 <T类>显式 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> 为真且 std::is_convertible_v 为假.

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

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

I have a class:

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

and there is a lib-func that I can't modify:

extern bool loadData( const string& strSymbol );

If there is a local variable:

Symbol_t   symbol( "123456" );

When I need to call loadData, I dare not do it like this:

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

I have to do like this:

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

My question: Is the first method correct? or I must use the second one?

Because I think that in Method 1, the iterators I passed to the constructor of std::string, are of two Different string_vew objects, and theoretically the result is undefined, even though we would get expected result with almost all of the C++ compilers.

Any hints will be appreciated! thanks.

解决方案

There is no need to use the c'tor taking a range. std::string has a constructor that operates in terms of std::string_view, number 10 in the list. The effect of which is

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.

Since both conditions hold for std::string_view itself, we can write the call to loadData as simply:

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

相关文章