web-dev-qa-db-ja.com

std :: string_viewからstd :: stringを正しく作成する方法は?

私はクラスを持っています:

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

私の質問:最初の方法は正しいですか?または私は2番目のものを使用する必要がありますか?

方法1では、std :: stringのコンストラクターに渡したイテレーターは2つの異なるstring_vewオブジェクトのものであり、ほとんどすべてのC++コンパイラーで期待どおりの結果が得られるとしても、結果は理論的には未定義です。

ヒントはありがたいです!ありがとう。

3
Leon

最初の方法は正しいですか?

strVwは同一のstring_viewsを返すため、すべて同じm_Vを指し、サイズが同じです。

ここでの正確さは、strVwの実装方法によって異なります。

または私は2番目のものを使用する必要がありますか?

私は変換関数を作成します:

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

そしてそれを使う:

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

このメソッドは、strVwの実装に関係なく安全です。

0

C++に文字列形式に変換したいstring_viewがある場合(たとえば、すべての分析を行った後で関数に戻ることができる)、次のようにして変更を加えることができます。

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

逆に、文字列からstring_viewを取得するには(その文字列へのポインタを取得するには)、次のようにします。

string s;
string_view sv = string_view(s);

部分文字列やその他のさまざまな操作は、文字列と同じようにstring_viewでも実行できることに注意してください。

0
Adrian