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

时间:2019-12-20 11:15:23

标签: c++ string reference iterator string-view

我有一堂课

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 ++编译器。

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

3 个答案:

答案 0 :(得分:1)

不需要使用c'tor进行测距。 std::string具有一个转换构造函数,该构造函数根据列表中的std::string_viewnumber 10进行操作。效果是

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

就像用std::basic_string_view<CharT, Traits> sv = t;一样,将t转换为字符串视图sv,然后用sv的内容来初始化字符串,就像通过basic_string(sv.data(), sv.size(), alloc)一样。仅当std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>>为true并且std::is_convertible_v<const T&, const CharT*>为false时,此重载才参与重载解析。

由于两个条件都适用于std::string_view本身,我们可以简单地将调用写入loadData

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

答案 1 :(得分: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,此方法都是安全的。

答案 2 :(得分:0)

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

#include <vector>
#include <utility>
#include <iostream>
#include <queue>
#include <array>

std::array<std::vector<std::pair<int, int> >, 6> adjacency_list;
std::array<bool, 7> visited;
std::array<int, 7> dist = { -1 };
int main() {

    dist.at(0) = 0;
    visited.at(0) = 1;

    for (int i = 1; i <= 6; i++) {
        int a, b, c;
        std::cin >> a >> b >> c;
        adjacency_list.at(a).emplace_back(b, c);
        adjacency_list.at(b).emplace_back(a, c);
    }

    std::queue<int>q;

    q.push(0);

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        for (auto i = adjacency_list.at(current).begin(); i != adjacency_list.at(current).end(); i++) {
            if (!visited.at(i->first)) {
                q.push(i->first);
                dist.at(i->first) = dist.at(current) + i->second;
                visited.at(i->first) = true;
            }
        }
    }

    for (int i = 0; i < 7; i++) {
        std::cout << i << ' ' << dist.at(i) << "\n";
    }

    return 0;
}

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

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

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