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

你离开我真会死。 提交于 2020-07-09 02:47:19

问题


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.


回答1:


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



回答2:


Is the first method correct?

It is, since strVw returns identical string_views: they all point to the same m_V and have the same size.

The correctness here depends on how strVw is implemented.

or I must use the second one?

I would create a conversion function:

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

And use that:

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

This method is safe regardless of strVw implementation.




回答3:


If you have some string_view in C++ that you want to convert into string format (so you can return to a function after doing all your analyses, for example), you can make that change by doing this:

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

Going the other way, to get a string_view from a string (so to get a pointer to that string) you can do this:

string s;
string_view sv = string_view(s);

Note that substring and a variety of other operations can be performed on string_view just as on string.



来源:https://stackoverflow.com/questions/59424390/how-to-correctly-create-stdstring-from-a-stdstring-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!